diff --git a/spine-flutter/.gitignore b/spine-flutter/.gitignore new file mode 100644 index 000000000..96486fd93 --- /dev/null +++ b/spine-flutter/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/spine-flutter/.metadata b/spine-flutter/.metadata new file mode 100644 index 000000000..98dc0b2ae --- /dev/null +++ b/spine-flutter/.metadata @@ -0,0 +1,42 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + channel: stable + +project_type: plugin_ffi + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: android + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: ios + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: linux + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: macos + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + - platform: windows + create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/spine-flutter/.pubignore b/spine-flutter/.pubignore new file mode 100644 index 000000000..95e564141 --- /dev/null +++ b/spine-flutter/.pubignore @@ -0,0 +1,3 @@ +!src/spine-cpp +!ios/Classes/spine-cpp +!macos/Classes/spine-cpp \ No newline at end of file diff --git a/spine-flutter/CHANGELOG.md b/spine-flutter/CHANGELOG.md new file mode 100644 index 000000000..877ac40a7 --- /dev/null +++ b/spine-flutter/CHANGELOG.md @@ -0,0 +1,34 @@ +# 4.2.11 +* Update README.md with setup and development instructions. + +# 4.2.10 +* Update README.md to point to Junji's Dart-only Spine runtime. + +# 4.2.9 +* Fix atlas parsing. + +# 4.2.8 +* Change reversed positional argument order in `SpineWidget` constructors. + +# 4.2.7 +* Change package name from `esotericsoftware_spine_flutter` to `spine_flutter`. + +# 4.2.6 +* Fix analyzer errors, fix code style to adhere to Dart standards. + +# 4.2.5 +* Implemented batching of render commands, reducing the number of draw calls. 60/120fps for 100 Spineboys on all platforms. + +# 0.0.4 +* Clean-up `fromAsset()` factory methods so the atlas comes before skeleton data file name. +* Rename `Vector2` to `Vec2`. +* Make the bundle configurable in `SpineWidget.asset()`. + +# 0.0.3 +* Lower macOS deployment target to 10.11. + +# 0.0.2 +* Fix package name in build system `spine_flutter` > `esotericsoftware_spine_flutter`. + +# 0.0.1 +Initial test release. \ No newline at end of file diff --git a/spine-flutter/LICENSE b/spine-flutter/LICENSE new file mode 100644 index 000000000..98b000b9c --- /dev/null +++ b/spine-flutter/LICENSE @@ -0,0 +1,26 @@ +Spine Runtimes License Agreement +Last updated September 24, 2021. Replaces all prior versions. + +Copyright (c) 2013-2021, Esoteric Software LLC + +Integration of the Spine Runtimes into software or otherwise creating +derivative works of the Spine Runtimes is permitted under the terms and +conditions of Section 2 of the Spine Editor License Agreement: +http://esotericsoftware.com/spine-editor-license + +Otherwise, it is permitted to integrate the Spine Runtimes into software +or otherwise create derivative works of the Spine Runtimes (collectively, +"Products"), provided that each user of the Products must obtain their own +Spine Editor license and redistribution of the Products in any form must +include this license and copyright notice. + +THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, +BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/spine-flutter/README.md b/spine-flutter/README.md new file mode 100644 index 000000000..83348a374 --- /dev/null +++ b/spine-flutter/README.md @@ -0,0 +1,77 @@ +# spine-flutter + +The spine-godot runtime provides functionality to load, manipulate and render [Spine](https://esotericsoftware.com) skeletal animation data using [Flutter](https://flutter.dev/). spine-flutter is based on [spine-cpp](../spine-cpp) and supports desktop and mobile Flutter deployment targets. spine-flutter does not support Flutter's web deployment target. + +# See the [spine-flutter documentation](https://esotericsoftware.com/spine-flutter) for in-depth information. + +The `spine_flutter` package name was previously used to publish the [Spine Flutter Runtime in plain Dart](https://github.com/jtakakura/spine_flutter/) by Junji Takakura. Junji has kindly transferred the package name to us and is now publishing his Dart-only Spine Flutter Runtime under the package name [spine_flutter_dart](https://pub.dev/packages/spine_flutter_dart). + +## Licensing + +You are welcome to evaluate the Spine Runtimes and the examples we provide in this repository free of charge. + +You can integrate the Spine Runtimes into your software free of charge, but users of your software must have their own [Spine license](https://esotericsoftware.com/spine-purchase). Please make your users aware of this requirement! This option is often chosen by those making development tools, such as an SDK, game toolkit, or software library. + +In order to distribute your software containing the Spine Runtimes to others that don't have a Spine license, you need a [Spine license](https://esotericsoftware.com/spine-purchase) at the time of integration. Then you can distribute your software containing the Spine Runtimes however you like, provided others don't modify it or use it to create new software. If others want to do that, they'll need their own Spine license. + +For the official legal terms governing the Spine Runtimes, please read the [Spine Runtimes License Agreement](https://esotericsoftware.com/spine-runtimes-license) and Section 2 of the [Spine Editor License Agreement](https://esotericsoftware.com/spine-editor-license#s2). + +## Spine version + +spine-flutter works with data exported from Spine 4.2.xx. + +spine-flutter supports all Spine features, except two-color tinting and the screen blend mode. + +## Supported platforms +The spine-flutter runtime works on desktop, mobile and web. Web deployment requires canvaskit, which will add about 2mb of dependencies to your web deployment. You can compile your app for web with Canvaskit like this: + +``` +flutter build web --web-renderer canvaskit +``` + +## Setup +To add `spine_flutter` to your Flutter project, add the following dependency to your `pubspec.yaml` file: + +```yaml +dependencies: + ... + spine_flutter: ^4.2.11 +``` + +In your `main()`, add these two lines in the beginning to initialize the Spine Flutter runtime: + +```dart +void main() { + WidgetsFlutterBinding.ensureInitialized(); + await initSpineFlutter(enableMemoryDebugging: false); + ... +} +``` + +## Example +If you have pulled the `spine_flutter` package from [pub.dev](https://pub.dev) directly, you can run the example in the `example/` folder as is: + +```bash +cd path/to/downloaded/spine_flutter +cd example +flutter run +``` + +Otherwise you can run the example like this: + +1. install the [Flutter SDK](https://docs.flutter.dev/get-started/install), then run `flutter doctor` which will instruct you what other dependencies to install. +2. Clone this repository `git clone https://github.com/esotericsoftware/spine-runtimes` +3. Run `setup.sh` in the `spine-flutter/` folder. On Windows, you can use [Git Bash](https://gitforwindows.org/) included in Git for Window to run the `setup.sh` Bash script. + +You can then open `spine-flutter` in an IDE or editor of your choice that supports Flutter, like [IntelliJ IDEA/Android Studio](https://docs.flutter.dev/get-started/editor?tab=androidstudio) or [Visual Studio Code](https://docs.flutter.dev/get-started/editor?tab=vscode) to inspect and run the example. + +Alternatively, you can run the example from the [command line](https://docs.flutter.dev/get-started/test-drive?tab=terminal). + +## Development +If all you modify are the Dart sources of the plugin, then the development setup is the same as the setup described under "Example" above. + +If you need to work on the `dart:ffi` bindings for `spine-cpp`, you will also need to install [Emscripten](https://emscripten.org/docs/getting_started/downloads.html). + +To generate the bindings based on the `src/spine_flutter.h` header, run `dart run ffigen --config ffigen.yaml`. After the bindings have been generated, you must replace the line `import 'dart:ffi' as ffi;` with `import 'ffi_proxy.dart' as ffi;` in the file `src/spine_flutter_bindings_generated.dart`. Otherwise the bindings will not compile for the web. + +If you made changes to `spine-cpp` or the source files in `src/`, you must run `compile-wasm.sh`. This will compile `spine-cpp` and the bindings for the Web and place updated versions of `libspine_flutter.js` and `libspine_flutter.wasm` in the `lib/assets/` folder. For web builds, the `initSpineFlutterFFI()` function in `lib/init_web.dart` will load these files from the package's asset bundle. diff --git a/spine-flutter/analysis_options.yaml b/spine-flutter/analysis_options.yaml new file mode 100644 index 000000000..a5744c1cf --- /dev/null +++ b/spine-flutter/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/spine-flutter/android/.gitignore b/spine-flutter/android/.gitignore new file mode 100644 index 000000000..161bdcdaf --- /dev/null +++ b/spine-flutter/android/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.cxx diff --git a/spine-flutter/android/build.gradle b/spine-flutter/android/build.gradle new file mode 100644 index 000000000..5b8e74c16 --- /dev/null +++ b/spine-flutter/android/build.gradle @@ -0,0 +1,59 @@ +// The Android Gradle Plugin builds the native code with the Android NDK. + +group 'com.example.spine_flutter' +version '1.0' + +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + // The Android Gradle Plugin knows how to build native code with the NDK. + classpath 'com.android.tools.build:gradle:7.1.2' + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: 'com.android.library' + +android { + // Bumping the plugin compileSdkVersion requires all clients of this plugin + // to bump the version in their app. + compileSdkVersion 31 + + // Bumping the plugin ndkVersion requires all clients of this plugin to bump + // the version in their app and to download a newer version of the NDK. + ndkVersion "21.1.6352462" + + // Invoke the shared CMake build with the Android Gradle Plugin. + externalNativeBuild { + cmake { + path "../src/CMakeLists.txt" + + // The default CMake version for the Android Gradle Plugin is 3.10.2. + // https://developer.android.com/studio/projects/install-ndk#vanilla_cmake + // + // The Flutter tooling requires that developers have CMake 3.10 or later + // installed. You should not increase this version, as doing so will cause + // the plugin to fail to compile for some customers of the plugin. + // version "3.10.2" + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + minSdkVersion 16 + } +} diff --git a/spine-flutter/android/settings.gradle b/spine-flutter/android/settings.gradle new file mode 100644 index 000000000..f4c5f6beb --- /dev/null +++ b/spine-flutter/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'spine_flutter' diff --git a/spine-flutter/android/src/main/AndroidManifest.xml b/spine-flutter/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000..1fef2d516 --- /dev/null +++ b/spine-flutter/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/spine-flutter/compile-wasm.sh b/spine-flutter/compile-wasm.sh new file mode 100755 index 000000000..b009bd4b3 --- /dev/null +++ b/spine-flutter/compile-wasm.sh @@ -0,0 +1,25 @@ +#!/bin/sh +dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +pushd $dir > /dev/null +mkdir -p lib/assets/ +# Need to use -O2, as -O3 applies the Closure compiler to native function names. +# The entries for exported functions in Module.asm will be scrambled so +# EmscriptenModule._fromJs() is unable to parse them and link them with original +# names set on the module, e.g. Module._spine_get_major_version. +emcc \ + -Isrc/spine-cpp/include \ + -O2 --closure 1 -fno-rtti -fno-exceptions -lc++abi -lc++ \ + -s STRICT=1 \ + -s LLD_REPORT_UNDEFINED \ + -s MODULARIZE=1 \ + -s ALLOW_MEMORY_GROWTH=1 \ + -s ALLOW_TABLE_GROWTH \ + -s MALLOC=emmalloc \ + -s EXPORT_ALL=1 \ + -s EXPORTED_FUNCTIONS='["_malloc", "_free"]' \ + --no-entry \ + -s EXPORT_NAME=libspine_flutter \ + src/spine_flutter.cpp `find src/spine-cpp/src -type f` \ + -o lib/assets/libspine_flutter.js + ls -lah lib/assets +popd \ No newline at end of file diff --git a/spine-flutter/example/.gitignore b/spine-flutter/example/.gitignore new file mode 100644 index 000000000..1eab1a228 --- /dev/null +++ b/spine-flutter/example/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/spine-flutter/example/README.md b/spine-flutter/example/README.md new file mode 100644 index 000000000..473078658 --- /dev/null +++ b/spine-flutter/example/README.md @@ -0,0 +1,16 @@ +# spine_flutter_example + +Demonstrates how to use the spine_flutter plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/spine-flutter/example/analysis_options.yaml b/spine-flutter/example/analysis_options.yaml new file mode 100644 index 000000000..61b6c4de1 --- /dev/null +++ b/spine-flutter/example/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/spine-flutter/example/android/.gitignore b/spine-flutter/example/android/.gitignore new file mode 100644 index 000000000..6f568019d --- /dev/null +++ b/spine-flutter/example/android/.gitignore @@ -0,0 +1,13 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +**/*.keystore +**/*.jks diff --git a/spine-flutter/example/android/app/build.gradle b/spine-flutter/example/android/app/build.gradle new file mode 100644 index 000000000..672a97c81 --- /dev/null +++ b/spine-flutter/example/android/app/build.gradle @@ -0,0 +1,71 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.spine_flutter_example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/spine-flutter/example/android/app/src/debug/AndroidManifest.xml b/spine-flutter/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..cf5d5093b --- /dev/null +++ b/spine-flutter/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/spine-flutter/example/android/app/src/main/AndroidManifest.xml b/spine-flutter/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..fd9393573 --- /dev/null +++ b/spine-flutter/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/spine-flutter/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/spine-flutter/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt new file mode 100644 index 000000000..e793a000d --- /dev/null +++ b/spine-flutter/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/spine-flutter/example/android/app/src/main/kotlin/com/example/spine_flutter_example/MainActivity.kt b/spine-flutter/example/android/app/src/main/kotlin/com/example/spine_flutter_example/MainActivity.kt new file mode 100644 index 000000000..f87d6d4f0 --- /dev/null +++ b/spine-flutter/example/android/app/src/main/kotlin/com/example/spine_flutter_example/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.spine_flutter_example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/spine-flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml b/spine-flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000..f74085f3f --- /dev/null +++ b/spine-flutter/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/spine-flutter/example/android/app/src/main/res/drawable/launch_background.xml b/spine-flutter/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000..304732f88 --- /dev/null +++ b/spine-flutter/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..db77bb4b7 Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..17987b79b Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..09d439148 Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..d5f1c8d34 Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/spine-flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/spine-flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..4d6372eeb Binary files /dev/null and b/spine-flutter/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/spine-flutter/example/android/app/src/main/res/values-night/styles.xml b/spine-flutter/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..06952be74 --- /dev/null +++ b/spine-flutter/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/spine-flutter/example/android/app/src/main/res/values/styles.xml b/spine-flutter/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..cb1ef8805 --- /dev/null +++ b/spine-flutter/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/spine-flutter/example/android/app/src/profile/AndroidManifest.xml b/spine-flutter/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 000000000..cf5d5093b --- /dev/null +++ b/spine-flutter/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + diff --git a/spine-flutter/example/android/build.gradle b/spine-flutter/example/android/build.gradle new file mode 100644 index 000000000..83ae22004 --- /dev/null +++ b/spine-flutter/example/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/spine-flutter/example/android/gradle.properties b/spine-flutter/example/android/gradle.properties new file mode 100644 index 000000000..94adc3a3f --- /dev/null +++ b/spine-flutter/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/spine-flutter/example/android/gradle/wrapper/gradle-wrapper.properties b/spine-flutter/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..cc5527d78 --- /dev/null +++ b/spine-flutter/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip diff --git a/spine-flutter/example/android/settings.gradle b/spine-flutter/example/android/settings.gradle new file mode 100644 index 000000000..44e62bcf0 --- /dev/null +++ b/spine-flutter/example/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/spine-flutter/example/assets/chibi/chibi-stickers.atlas b/spine-flutter/example/assets/chibi/chibi-stickers.atlas new file mode 100644 index 000000000..106cfcca4 --- /dev/null +++ b/spine-flutter/example/assets/chibi/chibi-stickers.atlas @@ -0,0 +1,409 @@ +chibi-stickers.webp +size:2017,491 +filter:Linear,Linear +scale:0.5 +common/angry-mark +bounds:1801,65,42,41 +common/big-purple-fear +bounds:1640,212,134,71 +offsets:0,0,134,72 +rotate:90 +common/big-tear +bounds:1454,15,33,82 +common/eye-3 +bounds:1611,2,15,26 +rotate:90 +common/eye-closed-happy +bounds:1685,348,25,9 +common/eye-dafault +bounds:1993,51,22,21 +common/eye-equal +bounds:1271,146,25,15 +common/eye-fire +bounds:1673,49,26,28 +common/eye-half-open +bounds:1475,101,26,16 +rotate:90 +common/eye-heart +bounds:1094,2,26,23 +rotate:90 +common/eye-reverse-v +bounds:1945,26,26,16 +common/eye-sideway-v +bounds:945,2,21,23 +rotate:90 +common/eye-slant-close +bounds:321,72,23,16 +common/eye-small-dot +bounds:1120,146,14,14 +offsets:0,1,15,15 +common/eye-sparkle +bounds:1810,4,30,29 +rotate:90 +common/eye-star +bounds:534,235,29,27 +rotate:90 +common/eye-twirl +bounds:970,2,21,23 +rotate:90 +common/eye-u +bounds:733,238,24,17 +rotate:90 +common/eye-x +bounds:1993,74,25,22 +rotate:90 +common/lamp +bounds:1319,2,47,65 +common/mouth-3 +bounds:1581,2,15,28 +rotate:90 +common/mouth-bracket +bounds:1450,2,34,11 +common/mouth-doubt +bounds:1639,2,26,15 +common/mouth-fangs +bounds:549,300,39,14 +rotate:90 +common/mouth-line +bounds:1601,212,36,7 +common/mouth-neutral +bounds:807,2,27,12 +common/mouth-o-tall +bounds:1993,101,22,33 +common/mouth-open-smile +bounds:359,33,36,22 +rotate:90 +common/mouth-rectangle +bounds:875,2,35,21 +common/mouth-reverse-v +bounds:1368,2,27,10 +common/mouth-s +bounds:2003,262,41,11 +rotate:90 +common/mouth-smile-little +bounds:1928,71,33,19 +rotate:90 +common/mouth-toungue-sticking-out +bounds:912,2,31,21 +common/mouth-u +bounds:383,33,36,19 +rotate:90 +common/mouth-v +bounds:563,235,27,14 +rotate:90 +common/mouth-x +bounds:1944,4,21,20 +common/purple-fear-lines +bounds:1807,108,48,28 +common/shadow +bounds:359,2,111,29 +offsets:1,1,113,31 +common/small-drop-line +bounds:1925,22,16,17 +rotate:90 +common/small-purple-fear +bounds:1941,451,54,38 +common/tear +bounds:995,3,20,19 +rotate:90 +erikari/arm +bounds:1383,99,28,90 +rotate:90 +erikari/arm-shoulder-decoration +bounds:1765,2,32,43 +rotate:90 +erikari/back-hair +bounds:565,348,158,141 +erikari/back-hair-long +bounds:2,235,220,254 +erikari/blush +bounds:555,43,29,18 +rotate:90 +erikari/body +bounds:575,2,70,98 +rotate:90 +erikari/bracelet +bounds:1841,2,33,11 +rotate:90 +erikari/collar +bounds:1320,99,61,62 +erikari/ear +bounds:105,2,34,42 +rotate:90 +erikari/eyebrow +bounds:2003,241,19,12 +offsets:0,0,20,12 +rotate:90 +erikari/hair-front +bounds:517,103,130,65 +rotate:90 +erikari/hair-side +bounds:1137,176,43,132 +rotate:90 +erikari/hat-border +bounds:1685,450,254,39 +erikari/hat-top +bounds:346,71,160,60 +rotate:90 +erikari/head-base +bounds:1060,221,143,125 +erikari/leg +bounds:2,8,28,101 +rotate:90 +erikari/leg-decoration +bounds:1412,2,36,13 +erikari/skirt +bounds:224,233,164,101 +erikari/strawberries-decoration +bounds:1271,163,112,56 +harri/arm +bounds:1320,69,28,90 +rotate:90 +harri/back-hair +bounds:725,348,158,141 +harri/back-hair-long +bounds:1412,17,40,80 +harri/beard +bounds:1397,2,10,11 +rotate:90 +harri/blush +bounds:1240,156,29,18 +luke/blush +bounds:1240,156,29,18 +nate/blush +bounds:1240,156,29,18 +spineboy/blush +bounds:1240,156,29,18 +harri/body +bounds:675,2,70,98 +rotate:90 +harri/body-decoration +bounds:287,2,70,67 +harri/ear +bounds:149,2,34,42 +rotate:90 +soeren/ear +bounds:149,2,34,42 +rotate:90 +spineboy/ear +bounds:149,2,34,42 +rotate:90 +harri/eyebrow +bounds:2003,305,22,12 +rotate:90 +harri/hair-front +bounds:1866,358,143,90 +harri/head-base +bounds:1205,221,143,125 +luke/head-base +bounds:1205,221,143,125 +soeren/head-base +bounds:1205,221,143,125 +spineboy/head-base +bounds:1205,221,143,125 +harri/leg +bounds:1017,132,28,101 +rotate:90 +harri/sword +bounds:565,264,185,82 +luke/arm +bounds:1489,71,28,90 +rotate:90 +luke/arm-shoulder-decoration +bounds:1801,36,31,27 +luke/back-hair +bounds:885,348,158,141 +luke/body +bounds:775,16,70,98 +rotate:90 +luke/eyebrow +bounds:836,2,27,12 +nate/eyebrow +bounds:836,2,27,12 +spineboy/eyebrow +bounds:836,2,27,12 +luke/face-cover +bounds:224,336,169,153 +luke/glasses-shadow +bounds:584,181,147,81 +luke/hair-decoration +bounds:408,103,130,107 +rotate:90 +luke/hair-front +bounds:1013,162,122,57 +luke/leg +bounds:1016,30,28,101 +rotate:90 +luke/shield +bounds:1495,131,88,104 +rotate:90 +luke/skirt +bounds:1845,73,81,31 +luke/sword +bounds:1601,139,102,71 +offsets:0,0,104,71 +mario/arm +bounds:1489,41,28,90 +rotate:90 +mario/back-hair +bounds:395,341,168,148 +mario/back-hair-long +bounds:194,2,86,91 +rotate:90 +mario/beard +bounds:1858,136,147,93 +mario/blush +bounds:1854,17,29,18 +mario/body +bounds:1018,60,70,98 +rotate:90 +mario/ear +bounds:1949,100,34,42 +rotate:90 +mario/eyebrow +bounds:287,71,32,17 +mario/hair-front +bounds:874,158,137,66 +mario/head-base +bounds:1350,221,143,125 +mario/leg +bounds:1137,146,28,101 +rotate:90 +misaki/arm +bounds:1489,11,28,90 +rotate:90 +misaki/back-hair +bounds:1045,348,158,141 +misaki/back-hair-long +bounds:2,38,190,195 +misaki/belt +bounds:1016,2,76,26 +misaki/blush +bounds:1925,40,29,18 +rotate:90 +misaki/body +bounds:1701,36,70,98 +rotate:90 +misaki/ear +bounds:1949,64,34,42 +rotate:90 +misaki/eyebrow +bounds:775,2,30,12 +misaki/glasses +bounds:875,72,141,35 +misaki/glasses-side +bounds:1240,146,8,23 +rotate:90 +misaki/hair-front +bounds:733,88,140,59 +misaki/hair-side +bounds:875,109,47,140 +rotate:90 +misaki/head-base +bounds:1495,221,143,125 +misaki/leg +bounds:1601,109,28,101 +rotate:90 +misaki/skirt +bounds:1385,129,108,90 +nate/arm +bounds:1581,49,28,90 +rotate:90 +nate/back-hair +bounds:1205,348,158,141 +nate/beard +bounds:584,111,147,68 +nate/body +bounds:1120,74,70,98 +rotate:90 +nate/ear +bounds:1845,37,34,42 +rotate:90 +nate/glasses +bounds:584,74,141,35 +nate/glasses-side +bounds:555,33,8,16 +rotate:90 +nate/hair-front +bounds:390,235,142,65 +nate/head-base +bounds:1713,232,143,125 +nate/leg +bounds:1704,108,28,101 +rotate:90 +sinisa/arm +bounds:1581,19,28,90 +rotate:90 +sinisa/back-hair +bounds:1365,348,158,141 +sinisa/beard +bounds:875,25,139,45 +sinisa/blush +bounds:1945,44,29,18 +sinisa/body +bounds:1119,2,70,98 +rotate:90 +sinisa/body-decoration +bounds:555,74,27,27 +sinisa/ear +bounds:1889,29,34,42 +sinisa/eyebrow +bounds:1997,451,38,18 +offsets:0,0,38,19 +rotate:90 +sinisa/hair-front +bounds:1713,138,143,92 +sinisa/head-base +bounds:1858,231,143,125 +sinisa/leg +bounds:1495,101,28,101 +rotate:90 +soeren/arm +bounds:1673,6,28,90 +rotate:90 +soeren/back-hair +bounds:194,90,150,141 +soeren/beard +bounds:408,33,145,68 +soeren/blush +bounds:1885,9,29,18 +soeren/body +bounds:1219,2,70,98 +rotate:90 +soeren/eyebrow +bounds:2003,329,27,12 +rotate:90 +soeren/glasses +bounds:395,302,152,37 +soeren/glasses-side +bounds:1486,2,7,20 +rotate:90 +soeren/glove +bounds:1368,14,42,53 +soeren/hair-front +bounds:752,233,159,113 +soeren/leg +bounds:1598,79,28,101 +rotate:90 +spineboy/arm +bounds:1857,106,28,90 +rotate:90 +spineboy/arm-decoration +bounds:534,266,32,29 +rotate:90 +spineboy/arm-shoulder-decoration +bounds:1973,19,23,23 +spineboy/back-hair +bounds:1525,348,158,141 +spineboy/body +bounds:1220,74,70,98 +rotate:90 +spineboy/glasses +bounds:1685,359,179,89 +spineboy/glasses-shadow +bounds:733,149,139,82 +spineboy/hair-front +bounds:913,226,145,120 +spineboy/leg +bounds:472,2,29,101 +rotate:90 diff --git a/spine-flutter/example/assets/chibi/chibi-stickers.skel b/spine-flutter/example/assets/chibi/chibi-stickers.skel new file mode 100644 index 000000000..61779a67b Binary files /dev/null and b/spine-flutter/example/assets/chibi/chibi-stickers.skel differ diff --git a/spine-flutter/example/assets/chibi/chibi-stickers.webp b/spine-flutter/example/assets/chibi/chibi-stickers.webp new file mode 100644 index 000000000..2232efb04 Binary files /dev/null and b/spine-flutter/example/assets/chibi/chibi-stickers.webp differ diff --git a/spine-flutter/example/assets/dragon-ess.skel b/spine-flutter/example/assets/dragon-ess.skel new file mode 100644 index 000000000..27e251df1 Binary files /dev/null and b/spine-flutter/example/assets/dragon-ess.skel differ diff --git a/spine-flutter/example/assets/dragon.atlas b/spine-flutter/example/assets/dragon.atlas new file mode 100644 index 000000000..bca5b1e1b --- /dev/null +++ b/spine-flutter/example/assets/dragon.atlas @@ -0,0 +1,123 @@ +dragon.png + size: 1024, 1024 + filter: Linear, Linear +back + bounds: 564, 534, 190, 185 +chest + bounds: 2, 645, 136, 122 +chin + bounds: 140, 619, 214, 146 +front-toe-a + bounds: 2, 862, 29, 50 + rotate: 90 +front-toe-b + bounds: 467, 835, 56, 57 + rotate: 90 +head + bounds: 756, 398, 296, 260 + rotate: 90 +left-front-leg + bounds: 599, 834, 84, 57 +left-front-thigh + bounds: 782, 819, 84, 72 +left-rear-leg + bounds: 356, 558, 206, 177 +left-rear-thigh + bounds: 216, 767, 91, 149 + rotate: 90 +left-wing01 + bounds: 2, 268, 264, 589 + rotate: 90 +left-wing02 + bounds: 2, 2, 264, 589 + rotate: 90 +right-front-leg + bounds: 113, 769, 101, 89 +right-front-thigh + bounds: 758, 709, 108, 108 +right-rear-leg + bounds: 640, 721, 116, 100 +right-rear-thigh + bounds: 367, 742, 91, 149 + rotate: 90 +right-rear-toe + bounds: 2, 781, 109, 77 +tail01 + bounds: 868, 696, 120, 153 + rotate: 90 +tail02 + bounds: 518, 737, 95, 120 + rotate: 90 +tail03 + bounds: 868, 818, 73, 92 + rotate: 90 +tail04 + bounds: 526, 835, 56, 71 + rotate: 90 +tail05 + bounds: 406, 839, 52, 59 + rotate: 90 +tail06 + bounds: 685, 823, 95, 68 +thiagobrayner + bounds: 54, 860, 350, 31 + +dragon_2.png + size: 1024, 1024 + filter: Linear, Linear +left-wing03 + bounds: 2, 534, 264, 589 + rotate: 90 +left-wing04 + bounds: 2, 268, 264, 589 + rotate: 90 +left-wing05 + bounds: 593, 209, 264, 589 +left-wing06 + bounds: 2, 2, 264, 589 + rotate: 90 + +dragon_3.png + size: 1024, 1024 + filter: Linear, Linear +left-wing07 + bounds: 2, 694, 264, 589 + rotate: 90 +left-wing08 + bounds: 2, 428, 264, 589 + rotate: 90 +left-wing09 + bounds: 593, 369, 264, 589 +right-wing01 + bounds: 2, 2, 365, 643 + rotate: 90 + +dragon_4.png + size: 1024, 1024 + filter: Linear, Linear +right-wing02 + bounds: 2, 369, 365, 643 +right-wing03 + bounds: 369, 369, 365, 643 +right-wing04 + bounds: 2, 2, 365, 643 + rotate: 90 + +dragon_5.png + size: 1024, 1024 + filter: Linear, Linear +right-wing05 + bounds: 2, 369, 365, 643 +right-wing06 + bounds: 369, 369, 365, 643 +right-wing07 + bounds: 2, 2, 365, 643 + rotate: 90 + +dragon_6.png + size: 1024, 1024 + filter: Linear, Linear +right-wing08 + bounds: 2, 2, 365, 643 +right-wing09 + bounds: 369, 2, 365, 643 diff --git a/spine-flutter/example/assets/dragon.png b/spine-flutter/example/assets/dragon.png new file mode 100644 index 000000000..f39141c47 Binary files /dev/null and b/spine-flutter/example/assets/dragon.png differ diff --git a/spine-flutter/example/assets/dragon_2.png b/spine-flutter/example/assets/dragon_2.png new file mode 100644 index 000000000..09429b5f8 Binary files /dev/null and b/spine-flutter/example/assets/dragon_2.png differ diff --git a/spine-flutter/example/assets/dragon_3.png b/spine-flutter/example/assets/dragon_3.png new file mode 100644 index 000000000..647bcb73b Binary files /dev/null and b/spine-flutter/example/assets/dragon_3.png differ diff --git a/spine-flutter/example/assets/dragon_4.png b/spine-flutter/example/assets/dragon_4.png new file mode 100644 index 000000000..8de760989 Binary files /dev/null and b/spine-flutter/example/assets/dragon_4.png differ diff --git a/spine-flutter/example/assets/dragon_5.png b/spine-flutter/example/assets/dragon_5.png new file mode 100644 index 000000000..5a98f7efa Binary files /dev/null and b/spine-flutter/example/assets/dragon_5.png differ diff --git a/spine-flutter/example/assets/dragon_6.png b/spine-flutter/example/assets/dragon_6.png new file mode 100644 index 000000000..49a39f648 Binary files /dev/null and b/spine-flutter/example/assets/dragon_6.png differ diff --git a/spine-flutter/example/assets/mix-and-match-pro.skel b/spine-flutter/example/assets/mix-and-match-pro.skel new file mode 100644 index 000000000..4cca62bce Binary files /dev/null and b/spine-flutter/example/assets/mix-and-match-pro.skel differ diff --git a/spine-flutter/example/assets/mix-and-match.atlas b/spine-flutter/example/assets/mix-and-match.atlas new file mode 100644 index 000000000..3cab05d5e --- /dev/null +++ b/spine-flutter/example/assets/mix-and-match.atlas @@ -0,0 +1,362 @@ +mix-and-match.png + size: 1024, 512 + filter: Linear, Linear + scale: 0.5 +base-head + bounds: 587, 2, 95, 73 +boy/arm-front + bounds: 558, 271, 36, 115 +boy/backpack + bounds: 235, 109, 119, 153 +boy/backpack-pocket + bounds: 328, 73, 34, 62 + rotate: 90 +boy/backpack-strap-front + bounds: 665, 79, 38, 88 +boy/backpack-up + bounds: 395, 364, 21, 70 + rotate: 90 +boy/body + bounds: 251, 264, 97, 132 + rotate: 90 +boy/boot-ribbon-front + bounds: 648, 131, 9, 11 +boy/collar + bounds: 744, 4, 73, 29 + rotate: 90 +boy/ear + bounds: 383, 109, 19, 23 + rotate: 90 +boy/eye-back-low-eyelid + bounds: 739, 284, 17, 6 + rotate: 90 +boy/eye-back-pupil + bounds: 832, 443, 8, 9 + rotate: 90 +boy/eye-back-up-eyelid + bounds: 558, 264, 23, 5 +boy/eye-back-up-eyelid-back + bounds: 802, 491, 19, 10 + rotate: 90 +boy/eye-front-low-eyelid + bounds: 386, 363, 22, 7 + rotate: 90 +boy/eye-front-pupil + bounds: 816, 389, 9, 9 +boy/eye-front-up-eyelid + bounds: 160, 71, 31, 6 + rotate: 90 +boy/eye-front-up-eyelid-back + bounds: 801, 434, 26, 9 + rotate: 90 +boy/eye-iris-back + bounds: 618, 264, 17, 17 +boy/eye-iris-front + bounds: 727, 264, 18, 18 +boy/eye-white-back + bounds: 580, 131, 20, 12 +boy/eye-white-front + bounds: 510, 130, 27, 13 +boy/eyebrow-back + bounds: 751, 88, 20, 11 + rotate: 90 +boy/eyebrow-front + bounds: 483, 130, 25, 11 +boy/hair-back + bounds: 494, 388, 122, 81 + rotate: 90 +boy/hair-bangs + bounds: 667, 284, 70, 37 +boy/hair-side + bounds: 789, 374, 25, 43 +boy/hand-backfingers + bounds: 467, 364, 19, 21 +boy/hand-front-fingers + bounds: 488, 364, 19, 21 +boy/hat + bounds: 615, 417, 93, 56 + rotate: 90 +boy/leg-front + bounds: 138, 104, 31, 158 +boy/mouth-close + bounds: 551, 365, 21, 5 + rotate: 90 +girl-blue-cape/mouth-close + bounds: 551, 365, 21, 5 + rotate: 90 +girl-spring-dress/mouth-close + bounds: 551, 365, 21, 5 + rotate: 90 +girl/mouth-close + bounds: 551, 365, 21, 5 + rotate: 90 +boy/mouth-smile + bounds: 705, 79, 29, 7 +boy/nose + bounds: 836, 473, 17, 10 + rotate: 90 +boy/pompom + bounds: 747, 273, 48, 43 + rotate: 90 +boy/zip + bounds: 648, 144, 14, 23 +girl-blue-cape/back-eyebrow + bounds: 602, 131, 18, 12 +girl-blue-cape/body-dress + bounds: 2, 264, 109, 246 +girl-blue-cape/body-ribbon + bounds: 615, 283, 50, 38 +girl-blue-cape/cape-back + bounds: 2, 69, 134, 193 +girl-blue-cape/cape-back-up + bounds: 386, 387, 123, 106 + rotate: 90 +girl-blue-cape/cape-ribbon + bounds: 675, 264, 50, 18 +girl-blue-cape/cape-shoulder-back + bounds: 751, 110, 49, 59 +girl-blue-cape/cape-shoulder-front + bounds: 113, 264, 62, 76 + rotate: 90 +girl-blue-cape/cape-up-front + bounds: 399, 264, 98, 117 + rotate: 90 +girl-blue-cape/ear + bounds: 775, 2, 19, 23 +girl-spring-dress/ear + bounds: 775, 2, 19, 23 +girl/ear + bounds: 775, 2, 19, 23 +girl-blue-cape/eye-back-low-eyelid + bounds: 802, 463, 17, 6 +girl-spring-dress/eye-back-low-eyelid + bounds: 802, 463, 17, 6 +girl/eye-back-low-eyelid + bounds: 802, 463, 17, 6 +girl-blue-cape/eye-back-pupil + bounds: 816, 367, 8, 9 +girl-spring-dress/eye-back-pupil + bounds: 816, 367, 8, 9 +girl/eye-back-pupil + bounds: 816, 367, 8, 9 +girl-blue-cape/eye-back-up-eyelid + bounds: 554, 131, 24, 12 +girl-spring-dress/eye-back-up-eyelid + bounds: 554, 131, 24, 12 +girl/eye-back-up-eyelid + bounds: 554, 131, 24, 12 +girl-blue-cape/eye-back-up-eyelid-back + bounds: 832, 453, 17, 11 + rotate: 90 +girl-spring-dress/eye-back-up-eyelid-back + bounds: 832, 453, 17, 11 + rotate: 90 +girl/eye-back-up-eyelid-back + bounds: 832, 453, 17, 11 + rotate: 90 +girl-blue-cape/eye-front-low-eyelid + bounds: 739, 303, 18, 6 + rotate: 90 +girl-spring-dress/eye-front-low-eyelid + bounds: 739, 303, 18, 6 + rotate: 90 +girl/eye-front-low-eyelid + bounds: 739, 303, 18, 6 + rotate: 90 +girl-blue-cape/eye-front-pupil + bounds: 816, 378, 9, 9 +girl-spring-dress/eye-front-pupil + bounds: 816, 378, 9, 9 +girl/eye-front-pupil + bounds: 816, 378, 9, 9 +girl-blue-cape/eye-front-up-eyelid + bounds: 392, 77, 30, 14 + rotate: 90 +girl-spring-dress/eye-front-up-eyelid + bounds: 392, 77, 30, 14 + rotate: 90 +girl/eye-front-up-eyelid + bounds: 392, 77, 30, 14 + rotate: 90 +girl-blue-cape/eye-front-up-eyelid-back + bounds: 455, 130, 26, 11 +girl-spring-dress/eye-front-up-eyelid-back + bounds: 455, 130, 26, 11 +girl/eye-front-up-eyelid-back + bounds: 455, 130, 26, 11 +girl-blue-cape/eye-iris-back + bounds: 637, 264, 17, 17 +girl-blue-cape/eye-iris-front + bounds: 802, 471, 18, 18 +girl-blue-cape/eye-white-back + bounds: 596, 264, 20, 16 +girl-spring-dress/eye-white-back + bounds: 596, 264, 20, 16 +girl-blue-cape/eye-white-front + bounds: 796, 5, 20, 16 + rotate: 90 +girl-spring-dress/eye-white-front + bounds: 796, 5, 20, 16 + rotate: 90 +girl/eye-white-front + bounds: 796, 5, 20, 16 + rotate: 90 +girl-blue-cape/front-eyebrow + bounds: 608, 149, 18, 12 + rotate: 90 +girl-blue-cape/hair-back + bounds: 508, 145, 117, 98 + rotate: 90 +girl-blue-cape/hair-bangs + bounds: 673, 419, 91, 40 + rotate: 90 +girl-blue-cape/hair-head-side-back + bounds: 196, 331, 30, 52 + rotate: 90 +girl-blue-cape/hair-head-side-front + bounds: 738, 323, 41, 42 +girl-blue-cape/hair-side + bounds: 473, 3, 36, 71 +girl-blue-cape/hand-front-fingers + bounds: 509, 365, 19, 21 +girl-spring-dress/hand-front-fingers + bounds: 509, 365, 19, 21 +girl-blue-cape/leg-front + bounds: 168, 72, 30, 158 + rotate: 90 +girl-blue-cape/mouth-smile + bounds: 736, 79, 29, 7 +girl-spring-dress/mouth-smile + bounds: 736, 79, 29, 7 +girl/mouth-smile + bounds: 736, 79, 29, 7 +girl-blue-cape/nose + bounds: 747, 264, 11, 7 +girl-spring-dress/nose + bounds: 747, 264, 11, 7 +girl/nose + bounds: 747, 264, 11, 7 +girl-blue-cape/sleeve-back + bounds: 767, 79, 42, 29 +girl-blue-cape/sleeve-front + bounds: 408, 76, 52, 119 + rotate: 90 +girl-spring-dress/arm-front + bounds: 596, 282, 17, 111 +girl-spring-dress/back-eyebrow + bounds: 801, 420, 18, 12 +girl-spring-dress/body-up + bounds: 179, 4, 64, 66 +girl-spring-dress/cloak-down + bounds: 775, 27, 50, 50 +girl-spring-dress/cloak-up + bounds: 360, 7, 64, 58 + rotate: 90 +girl-spring-dress/eye-iris-back + bounds: 656, 264, 17, 17 +girl-spring-dress/eye-iris-front + bounds: 814, 492, 18, 18 +girl-spring-dress/front-eyebrow + bounds: 822, 472, 18, 12 + rotate: 90 +girl-spring-dress/hair-back + bounds: 196, 363, 147, 93 + rotate: 90 +girl-spring-dress/hair-bangs + bounds: 696, 326, 91, 40 + rotate: 90 +girl-spring-dress/hair-head-side-back + bounds: 529, 76, 30, 52 +girl-spring-dress/hair-head-side-front + bounds: 781, 323, 41, 42 +girl-spring-dress/hair-side + bounds: 511, 3, 36, 71 +girl-spring-dress/leg-front + bounds: 171, 104, 30, 158 +girl-spring-dress/neck + bounds: 138, 70, 20, 32 +girl-spring-dress/shoulder-ribbon + bounds: 622, 131, 36, 24 + rotate: 90 +girl-spring-dress/skirt + bounds: 113, 328, 182, 81 + rotate: 90 +girl-spring-dress/underskirt + bounds: 2, 2, 175, 65 +girl/arm-front + bounds: 577, 395, 36, 115 +girl/back-eyebrow + bounds: 834, 492, 18, 12 + rotate: 90 +girl/bag-base + bounds: 191, 264, 62, 58 + rotate: 90 +girl/bag-strap-front + bounds: 385, 265, 12, 96 +girl/bag-top + bounds: 738, 367, 49, 50 +girl/body + bounds: 356, 130, 97, 132 +girl/boot-ribbon-front + bounds: 539, 130, 13, 13 +girl/eye-iris-back + bounds: 821, 424, 17, 17 +girl/eye-iris-front + bounds: 812, 443, 18, 18 +girl/eye-white-back + bounds: 814, 5, 20, 16 + rotate: 90 +girl/front-eyebrow + bounds: 816, 400, 18, 12 + rotate: 90 +girl/hair-back + bounds: 291, 363, 147, 93 + rotate: 90 +girl/hair-bangs + bounds: 715, 419, 91, 40 + rotate: 90 +girl/hair-flap-down-front + bounds: 288, 5, 70, 65 +girl/hair-head-side-back + bounds: 561, 77, 30, 52 +girl/hair-head-side-front + bounds: 757, 419, 41, 42 + rotate: 90 +girl/hair-patch + bounds: 245, 4, 66, 41 + rotate: 90 +girl/hair-side + bounds: 549, 3, 36, 71 +girl/hair-strand-back-1 + bounds: 684, 3, 58, 74 +girl/hair-strand-back-2 + bounds: 692, 171, 91, 58 + rotate: 90 +girl/hair-strand-back-3 + bounds: 615, 323, 92, 79 + rotate: 90 +girl/hair-strand-front-1 + bounds: 518, 269, 38, 94 +girl/hair-strand-front-2 + bounds: 593, 79, 70, 50 +girl/hair-strand-front-3 + bounds: 705, 88, 44, 81 +girl/hand-front-fingers + bounds: 530, 365, 19, 21 +girl/hat + bounds: 608, 169, 93, 82 + rotate: 90 +girl/leg-front + bounds: 203, 104, 30, 158 +girl/pompom + bounds: 757, 462, 48, 43 + rotate: 90 +girl/scarf + bounds: 455, 143, 119, 51 + rotate: 90 +girl/scarf-back + bounds: 420, 2, 72, 51 + rotate: 90 +girl/zip + bounds: 356, 109, 19, 25 + rotate: 90 diff --git a/spine-flutter/example/assets/mix-and-match.png b/spine-flutter/example/assets/mix-and-match.png new file mode 100644 index 000000000..441cd2a81 Binary files /dev/null and b/spine-flutter/example/assets/mix-and-match.png differ diff --git a/spine-flutter/example/assets/spineboy-pro.json b/spine-flutter/example/assets/spineboy-pro.json new file mode 100644 index 000000000..b4dd8b40f --- /dev/null +++ b/spine-flutter/example/assets/spineboy-pro.json @@ -0,0 +1,8707 @@ +{ +"skeleton": { + "hash": "itfFESDjM1c", + "spine": "4.1.23-beta", + "x": -188.63, + "y": -7.94, + "width": 418.45, + "height": 686.2, + "images": "./images/", + "audio": "" +}, +"bones": [ + { "name": "root", "rotation": 0.05 }, + { "name": "hip", "parent": "root", "y": 247.27 }, + { "name": "crosshair", "parent": "root", "x": 302.83, "y": 569.45, "color": "ff3f00ff" }, + { + "name": "aim-constraint-target", + "parent": "hip", + "length": 26.24, + "rotation": 19.61, + "x": 1.02, + "y": 5.62, + "color": "abe323ff" + }, + { "name": "rear-foot-target", "parent": "root", "x": 61.91, "y": 0.42, "color": "ff3f00ff" }, + { "name": "rear-leg-target", "parent": "rear-foot-target", "x": -33.91, "y": 37.34, "color": "ff3f00ff" }, + { + "name": "rear-thigh", + "parent": "hip", + "length": 85.72, + "rotation": -72.54, + "x": 8.91, + "y": -5.63, + "color": "ff000dff" + }, + { + "name": "rear-shin", + "parent": "rear-thigh", + "length": 121.88, + "rotation": -19.83, + "x": 86.1, + "y": -1.33, + "color": "ff000dff" + }, + { + "name": "rear-foot", + "parent": "rear-shin", + "length": 51.58, + "rotation": 45.78, + "x": 121.46, + "y": -0.76, + "color": "ff000dff" + }, + { + "name": "back-foot-tip", + "parent": "rear-foot", + "length": 50.3, + "rotation": -0.85, + "x": 51.17, + "y": 0.24, + "transform": "noRotationOrReflection", + "color": "ff000dff" + }, + { "name": "board-ik", "parent": "root", "x": -131.78, "y": 69.09, "color": "4c56ffff" }, + { "name": "clipping", "parent": "root" }, + { "name": "hoverboard-controller", "parent": "root", "rotation": -0.28, "x": -329.69, "y": 69.82, "color": "ff0004ff" }, + { "name": "exhaust1", "parent": "hoverboard-controller", "rotation": 3.02, "x": -249.68, "y": 53.39 }, + { "name": "exhaust2", "parent": "hoverboard-controller", "rotation": 26.34, "x": -191.6, "y": -22.92 }, + { + "name": "exhaust3", + "parent": "hoverboard-controller", + "rotation": -12.34, + "x": -236.03, + "y": 80.54, + "scaleX": 0.7847, + "scaleY": 0.7847 + }, + { "name": "portal-root", "parent": "root", "x": 12.9, "y": 328.54, "scaleX": 2.0334, "scaleY": 2.0334 }, + { "name": "flare1", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare10", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare2", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare3", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare4", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare5", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare6", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare7", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare8", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { "name": "flare9", "parent": "portal-root", "x": -6.34, "y": -161.57 }, + { + "name": "torso", + "parent": "hip", + "length": 42.52, + "rotation": 103.82, + "x": -1.62, + "y": 4.9, + "color": "e0da19ff" + }, + { "name": "torso2", "parent": "torso", "length": 42.52, "x": 42.52, "color": "e0da19ff" }, + { "name": "torso3", "parent": "torso2", "length": 42.52, "x": 42.52, "color": "e0da19ff" }, + { "name": "front-shoulder", "parent": "torso3", "rotation": 255.89, "x": 18.72, "y": 19.33, "color": "00ff04ff" }, + { "name": "front-upper-arm", "parent": "front-shoulder", "length": 69.45, "rotation": -87.51, "color": "00ff04ff" }, + { + "name": "front-bracer", + "parent": "front-upper-arm", + "length": 40.57, + "rotation": 18.3, + "x": 68.8, + "y": -0.68, + "color": "00ff04ff" + }, + { + "name": "front-fist", + "parent": "front-bracer", + "length": 65.39, + "rotation": 12.43, + "x": 40.57, + "y": 0.2, + "color": "00ff04ff" + }, + { "name": "front-foot-target", "parent": "root", "x": -13.53, "y": 0.04, "color": "ff3f00ff" }, + { "name": "front-leg-target", "parent": "front-foot-target", "x": -28.4, "y": 29.06, "color": "ff3f00ff" }, + { + "name": "front-thigh", + "parent": "hip", + "length": 74.81, + "rotation": -95.51, + "x": -17.46, + "y": -11.64, + "color": "00ff04ff" + }, + { + "name": "front-shin", + "parent": "front-thigh", + "length": 128.77, + "rotation": -2.21, + "x": 78.69, + "y": 1.6, + "color": "00ff04ff" + }, + { + "name": "front-foot", + "parent": "front-shin", + "length": 41.01, + "rotation": 51.27, + "x": 128.76, + "y": -0.34, + "color": "00ff04ff" + }, + { + "name": "front-foot-tip", + "parent": "front-foot", + "length": 56.03, + "rotation": -1.68, + "x": 41.42, + "y": -0.09, + "transform": "noRotationOrReflection", + "color": "00ff04ff" + }, + { "name": "back-shoulder", "parent": "torso3", "rotation": -104.11, "x": 7.32, "y": -19.22, "color": "ff000dff" }, + { "name": "rear-upper-arm", "parent": "back-shoulder", "length": 51.94, "rotation": -65.45, "color": "ff000dff" }, + { "name": "rear-bracer", "parent": "rear-upper-arm", "length": 34.56, "rotation": 23.15, "x": 51.36, "color": "ff000dff" }, + { + "name": "gun", + "parent": "rear-bracer", + "length": 43.11, + "rotation": -5.43, + "x": 34.42, + "y": -0.45, + "color": "ff000dff" + }, + { "name": "gun-tip", "parent": "gun", "rotation": 7.1, "x": 200.78, "y": 52.5, "color": "ff0000ff" }, + { + "name": "neck", + "parent": "torso3", + "length": 25.45, + "rotation": -31.54, + "x": 42.46, + "y": -0.31, + "color": "e0da19ff" + }, + { + "name": "head", + "parent": "neck", + "length": 131.79, + "rotation": 26.1, + "x": 27.66, + "y": -0.26, + "color": "e0da19ff" + }, + { + "name": "hair1", + "parent": "head", + "length": 47.23, + "rotation": -49.1, + "x": 149.83, + "y": -59.77, + "color": "e0da19ff" + }, + { + "name": "hair2", + "parent": "hair1", + "length": 55.57, + "rotation": 50.42, + "x": 47.23, + "y": 0.19, + "color": "e0da19ff" + }, + { + "name": "hair3", + "parent": "head", + "length": 62.22, + "rotation": -32.17, + "x": 164.14, + "y": 3.68, + "color": "e0da19ff" + }, + { + "name": "hair4", + "parent": "hair3", + "length": 80.28, + "rotation": 83.71, + "x": 62.22, + "y": -0.04, + "color": "e0da19ff" + }, + { "name": "hoverboard-thruster-front", "parent": "hoverboard-controller", "rotation": -29.2, "x": 95.77, "y": -2.99, "transform": "noRotationOrReflection" }, + { "name": "hoverboard-thruster-rear", "parent": "hoverboard-controller", "rotation": -29.2, "x": -76.47, "y": -4.88, "transform": "noRotationOrReflection" }, + { "name": "hoverglow-front", "parent": "hoverboard-thruster-front", "rotation": 0.17, "x": -1.78, "y": -37.79 }, + { "name": "hoverglow-rear", "parent": "hoverboard-thruster-rear", "rotation": 0.17, "x": 1.06, "y": -35.66 }, + { "name": "muzzle", "parent": "rear-bracer", "rotation": 3.06, "x": 242.34, "y": 34.26, "color": "ffb900ff" }, + { "name": "muzzle-ring", "parent": "muzzle", "color": "ffb900ff" }, + { "name": "muzzle-ring2", "parent": "muzzle", "color": "ffb900ff" }, + { "name": "muzzle-ring3", "parent": "muzzle", "color": "ffb900ff" }, + { "name": "muzzle-ring4", "parent": "muzzle", "color": "ffb900ff" }, + { "name": "portal", "parent": "portal-root" }, + { "name": "portal-shade", "parent": "portal-root" }, + { "name": "portal-streaks1", "parent": "portal-root" }, + { "name": "portal-streaks2", "parent": "portal-root" }, + { "name": "side-glow1", "parent": "hoverboard-controller", "x": -110.56, "y": 2.62, "color": "000effff" }, + { + "name": "side-glow2", + "parent": "hoverboard-controller", + "x": -110.56, + "y": 2.62, + "scaleX": 0.738, + "scaleY": 0.738, + "color": "000effff" + }, + { "name": "head-control", "parent": "head", "x": 110.21, "color": "00a220ff" } +], +"slots": [ + { "name": "portal-bg", "bone": "portal" }, + { "name": "portal-shade", "bone": "portal-shade" }, + { "name": "portal-streaks2", "bone": "portal-streaks2", "blend": "additive" }, + { "name": "portal-streaks1", "bone": "portal-streaks1", "blend": "additive" }, + { "name": "portal-flare8", "bone": "flare8", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare9", "bone": "flare9", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare10", "bone": "flare10", "color": "c3cbffff", "blend": "additive" }, + { "name": "clipping", "bone": "clipping" }, + { "name": "exhaust3", "bone": "exhaust3", "color": "5eb4ffff", "blend": "additive" }, + { "name": "hoverboard-thruster-rear", "bone": "hoverboard-thruster-rear" }, + { "name": "hoverboard-thruster-front", "bone": "hoverboard-thruster-front" }, + { "name": "hoverboard-board", "bone": "hoverboard-controller" }, + { "name": "side-glow1", "bone": "side-glow1", "color": "ff8686ff", "blend": "additive" }, + { "name": "side-glow3", "bone": "side-glow1", "color": "ff8686ff", "blend": "additive" }, + { "name": "side-glow2", "bone": "side-glow2", "color": "ff8686ff", "blend": "additive" }, + { "name": "hoverglow-front", "bone": "hoverglow-front", "color": "5eb4ffff", "blend": "additive" }, + { "name": "hoverglow-rear", "bone": "hoverglow-rear", "color": "5eb4ffff", "blend": "additive" }, + { "name": "exhaust1", "bone": "exhaust2", "color": "5eb4ffff", "blend": "additive" }, + { "name": "exhaust2", "bone": "exhaust1", "color": "5eb4ffff", "blend": "additive" }, + { "name": "rear-upper-arm", "bone": "rear-upper-arm", "attachment": "rear-upper-arm" }, + { "name": "rear-bracer", "bone": "rear-bracer", "attachment": "rear-bracer" }, + { "name": "gun", "bone": "gun", "attachment": "gun" }, + { "name": "rear-foot", "bone": "rear-foot", "attachment": "rear-foot" }, + { "name": "rear-thigh", "bone": "rear-thigh", "attachment": "rear-thigh" }, + { "name": "rear-shin", "bone": "rear-shin", "attachment": "rear-shin" }, + { "name": "neck", "bone": "neck", "attachment": "neck" }, + { "name": "torso", "bone": "torso", "attachment": "torso" }, + { "name": "front-upper-arm", "bone": "front-upper-arm", "attachment": "front-upper-arm" }, + { "name": "head", "bone": "head", "attachment": "head" }, + { "name": "eye", "bone": "head", "attachment": "eye-indifferent" }, + { "name": "front-thigh", "bone": "front-thigh", "attachment": "front-thigh" }, + { "name": "front-foot", "bone": "front-foot", "attachment": "front-foot" }, + { "name": "front-shin", "bone": "front-shin", "attachment": "front-shin" }, + { "name": "mouth", "bone": "head", "attachment": "mouth-smile" }, + { "name": "goggles", "bone": "head", "attachment": "goggles" }, + { "name": "front-bracer", "bone": "front-bracer", "attachment": "front-bracer" }, + { "name": "front-fist", "bone": "front-fist", "attachment": "front-fist-closed" }, + { "name": "muzzle", "bone": "muzzle" }, + { "name": "head-bb", "bone": "head" }, + { "name": "portal-flare1", "bone": "flare1", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare2", "bone": "flare2", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare3", "bone": "flare3", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare4", "bone": "flare4", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare5", "bone": "flare5", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare6", "bone": "flare6", "color": "c3cbffff", "blend": "additive" }, + { "name": "portal-flare7", "bone": "flare7", "color": "c3cbffff", "blend": "additive" }, + { "name": "crosshair", "bone": "crosshair" }, + { "name": "muzzle-glow", "bone": "gun-tip", "color": "ffffff00", "blend": "additive" }, + { "name": "muzzle-ring", "bone": "muzzle-ring", "color": "d8baffff", "blend": "additive" }, + { "name": "muzzle-ring2", "bone": "muzzle-ring2", "color": "d8baffff", "blend": "additive" }, + { "name": "muzzle-ring3", "bone": "muzzle-ring3", "color": "d8baffff", "blend": "additive" }, + { "name": "muzzle-ring4", "bone": "muzzle-ring4", "color": "d8baffff", "blend": "additive" } +], +"ik": [ + { + "name": "aim-ik", + "order": 13, + "bones": [ "rear-upper-arm" ], + "target": "crosshair", + "mix": 0 + }, + { + "name": "aim-torso-ik", + "order": 8, + "bones": [ "aim-constraint-target" ], + "target": "crosshair" + }, + { + "name": "board-ik", + "order": 1, + "bones": [ "hoverboard-controller" ], + "target": "board-ik" + }, + { + "name": "front-foot-ik", + "order": 6, + "bones": [ "front-foot" ], + "target": "front-foot-target" + }, + { + "name": "front-leg-ik", + "order": 4, + "bones": [ "front-thigh", "front-shin" ], + "target": "front-leg-target", + "bendPositive": false + }, + { + "name": "rear-foot-ik", + "order": 7, + "bones": [ "rear-foot" ], + "target": "rear-foot-target" + }, + { + "name": "rear-leg-ik", + "order": 5, + "bones": [ "rear-thigh", "rear-shin" ], + "target": "rear-leg-target", + "bendPositive": false + } +], +"transform": [ + { + "name": "aim-front-arm-transform", + "order": 11, + "bones": [ "front-upper-arm" ], + "target": "aim-constraint-target", + "rotation": -180, + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "aim-head-transform", + "order": 10, + "bones": [ "head" ], + "target": "aim-constraint-target", + "rotation": 84.3, + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "aim-rear-arm-transform", + "order": 12, + "bones": [ "rear-upper-arm" ], + "target": "aim-constraint-target", + "x": 57.7, + "y": 56.4, + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "aim-torso-transform", + "order": 9, + "bones": [ "torso" ], + "target": "aim-constraint-target", + "rotation": 69.5, + "shearY": -36, + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "front-foot-board-transform", + "order": 2, + "bones": [ "front-foot-target" ], + "target": "hoverboard-controller", + "x": -69.8, + "y": 20.7, + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "rear-foot-board-transform", + "order": 3, + "bones": [ "rear-foot-target" ], + "target": "hoverboard-controller", + "x": 86.6, + "y": 21.3, + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "shoulder", + "bones": [ "back-shoulder" ], + "target": "front-shoulder", + "x": 40.17, + "y": -1.66, + "mixRotate": 0, + "mixX": -1, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "toes-board", + "order": 14, + "bones": [ "front-foot-tip", "back-foot-tip" ], + "target": "hoverboard-controller", + "mixRotate": 0, + "mixX": 0, + "mixScaleX": 0, + "mixShearY": 0 + } +], +"skins": [ + { + "name": "default", + "attachments": { + "clipping": { + "clipping": { + "type": "clipping", + "end": "head-bb", + "vertexCount": 9, + "vertices": [ 66.76, 509.48, 19.98, 434.54, 5.34, 336.28, 22.19, 247.93, 77.98, 159.54, 182.21, -97.56, 1452.26, -99.8, 1454.33, 843.61, 166.57, 841.02 ], + "color": "ce3a3aff" + } + }, + "crosshair": { + "crosshair": { "width": 89, "height": 89 } + }, + "exhaust1": { + "hoverglow-small": { "scaleX": 0.4629, "scaleY": 0.8129, "rotation": -83.07, "width": 274, "height": 75 } + }, + "exhaust2": { + "hoverglow-small": { + "x": 0.01, + "y": -0.76, + "scaleX": 0.4208, + "scaleY": 0.8403, + "rotation": -89.25, + "width": 274, + "height": 75 + } + }, + "exhaust3": { + "hoverglow-small": { "scaleX": 0.4629, "scaleY": 0.8129, "rotation": -83.07, "width": 274, "height": 75 } + }, + "eye": { + "eye-indifferent": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 66, -36.8, -91.35, 0.3, 46, 73.41, -91.35, 0.7, 2, 66, -87.05, -13.11, 0.70968, 46, 23.16, -13.11, 0.29032, 2, 66, -12.18, 34.99, 0.82818, 46, 98.03, 34.99, 0.17182, 2, 66, 38.07, -43.25, 0.59781, 46, 148.28, -43.25, 0.40219 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 93, + "height": 89 + }, + "eye-surprised": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 2, 66, -46.74, -89.7, 0.3, 46, 63.47, -89.7, 0.7, 2, 66, -77.58, -1.97, 0.71, 46, 32.63, -1.97, 0.29, 2, 66, 6.38, 27.55, 0.83, 46, 116.59, 27.55, 0.17, 2, 66, 37.22, -60.19, 0.6, 46, 147.44, -60.19, 0.4 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 93, + "height": 89 + } + }, + "front-bracer": { + "front-bracer": { "x": 12.03, "y": -1.68, "rotation": 79.6, "width": 58, "height": 80 } + }, + "front-fist": { + "front-fist-closed": { "x": 35.5, "y": 6, "rotation": 67.16, "width": 75, "height": 82 }, + "front-fist-open": { "x": 39.57, "y": 7.76, "rotation": 67.16, "width": 86, "height": 87 } + }, + "front-foot": { + "front-foot": { + "type": "mesh", + "uvs": [ 0.59417, 0.23422, 0.62257, 0.30336, 0.6501, 0.37036, 0.67637, 0.38404, 0.72068, 0.4071, 0.76264, 0.42894, 1, 0.70375, 1, 1, 0.65517, 1, 0.46923, 0.99999, 0, 1, 0, 0.39197, 0.17846, 0, 0.49796, 0 ], + "triangles": [ 8, 9, 3, 4, 8, 3, 5, 8, 4, 6, 8, 5, 8, 6, 7, 11, 1, 10, 0, 12, 13, 0, 11, 12, 0, 1, 11, 9, 2, 3, 1, 2, 10, 9, 10, 2 ], + "vertices": [ 2, 38, 18.17, 41.57, 0.7896, 39, 12.46, 46.05, 0.2104, 2, 38, 24.08, 40.76, 0.71228, 39, 16.12, 41.34, 0.28772, 2, 38, 29.81, 39.98, 0.55344, 39, 19.67, 36.78, 0.44656, 2, 38, 32.81, 41.67, 0.38554, 39, 23, 35.89, 0.61446, 2, 38, 37.86, 44.52, 0.25567, 39, 28.61, 34.4, 0.74433, 2, 38, 42.65, 47.22, 0.17384, 39, 33.92, 32.99, 0.82616, 1, 39, 64.15, 14.56, 1, 1, 39, 64.51, -5.87, 1, 1, 39, 21.08, -6.64, 1, 2, 38, 44.67, -6.77, 0.5684, 39, -2.34, -6.97, 0.4316, 1, 38, 3.1, -48.81, 1, 1, 38, -26.73, -19.31, 1, 1, 38, -30.15, 15.69, 1, 1, 38, -1.84, 44.32, 1 ], + "hull": 14, + "edges": [ 14, 16, 16, 18, 18, 20, 4, 18, 20, 22, 24, 26, 22, 24, 12, 14, 10, 12, 2, 4, 2, 20, 4, 6, 6, 16, 2, 0, 0, 26, 6, 8, 8, 10 ], + "width": 126, + "height": 69 + } + }, + "front-shin": { + "front-shin": { + "type": "mesh", + "uvs": [ 0.90031, 0.05785, 1, 0.12828, 1, 0.21619, 0.9025, 0.31002, 0.78736, 0.35684, 0.78081, 0.39874, 0.77215, 0.45415, 0.77098, 0.51572, 0.84094, 0.63751, 0.93095, 0.7491, 0.95531, 0.7793, 0.78126, 0.87679, 0.5613, 1, 0.2687, 1, 0, 1, 0.00279, 0.96112, 0.01358, 0.81038, 0.02822, 0.60605, 0.08324, 0.45142, 0.18908, 0.31882, 0.29577, 0.2398, 0.30236, 0.14941, 0.37875, 0.05902, 0.53284, 0, 0.70538, 0, 0.41094, 0.71968, 0.40743, 0.54751, 0.41094, 0.4536, 0.4724, 0.35186, 0.33367, 0.27829, 0.50226, 0.31664, 0.65328, 0.67507, 0.60762, 0.52716, 0.6006, 0.45125, 0.62747, 0.37543, 0.6573, 0.3385, 0.27843, 0.32924, 0.18967, 0.45203, 0.16509, 0.58586, 0.18265, 0.7682, 0.50532, 0.24634, 0.59473, 0.17967, 0.60161, 0.10611, 0.51392, 0.04327, 0.72198, 0.28849, 0.82343, 0.20266, 0.86814, 0.11377, 0.79592, 0.04634, 0.44858, 0.15515, 0.25466, 0.96219, 0.53169, 0.9448, 0.7531, 0.8324 ], + "triangles": [ 24, 0, 47, 43, 23, 24, 47, 43, 24, 43, 22, 23, 42, 43, 47, 46, 47, 0, 42, 47, 46, 46, 0, 1, 48, 22, 43, 48, 43, 42, 21, 22, 48, 41, 48, 42, 45, 42, 46, 41, 42, 45, 46, 1, 2, 45, 46, 2, 40, 48, 41, 48, 20, 21, 29, 48, 40, 29, 20, 48, 44, 41, 45, 40, 41, 44, 3, 45, 2, 44, 45, 3, 30, 29, 40, 35, 30, 40, 36, 19, 20, 36, 20, 29, 44, 35, 40, 28, 29, 30, 4, 44, 3, 35, 44, 4, 34, 30, 35, 5, 35, 4, 34, 28, 30, 33, 28, 34, 37, 19, 36, 18, 19, 37, 27, 29, 28, 27, 28, 33, 36, 29, 27, 37, 36, 27, 5, 34, 35, 6, 34, 5, 33, 34, 6, 6, 32, 33, 7, 32, 6, 26, 37, 27, 38, 18, 37, 38, 37, 26, 17, 18, 38, 31, 32, 7, 31, 7, 8, 32, 25, 26, 38, 26, 25, 27, 33, 32, 32, 26, 27, 39, 38, 25, 17, 38, 39, 16, 17, 39, 51, 31, 8, 51, 8, 9, 11, 51, 9, 11, 9, 10, 31, 50, 25, 31, 25, 32, 50, 31, 51, 49, 39, 25, 49, 25, 50, 15, 16, 39, 49, 15, 39, 13, 49, 50, 14, 15, 49, 13, 14, 49, 12, 50, 51, 12, 51, 11, 13, 50, 12 ], + "vertices": [ -23.66, 19.37, -11.73, 28.98, 4.34, 30.83, 22.41, 24.87, 32.05, 16.48, 39.77, 16.83, 49.98, 17.3, 61.25, 18.5, 82.85, 26.78, 102.4, 36.46, 107.69, 39.09, 127.15, 26.97, 151.74, 11.65, 154.49, -12.18, 157.02, -34.07, 149.89, -34.66, 122.23, -36.97, 84.75, -40.09, 55.97, -38.88, 30.73, -33.05, 15.29, -26.03, -1.3, -27.41, -18.54, -23.09, -30.78, -11.79, -32.4, 2.27, 101.92, -6.52, 70.48, -10.44, 53.28, -12.14, 34.11, -9.28, 21.96, -22.13, 27.39, -7.59, 91.48, 12.28, 64.88, 5.44, 51.07, 3.26, 36.95, 3.85, 29.92, 5.5, 31.8, -25.56, 55.08, -30.19, 79.77, -29.37, 112.93, -24.09, 14.51, -8.83, 1.48, -2.95, -12.03, -3.94, -22.69, -12.41, 20.17, 9.71, 3.53, 16.16, -13.14, 17.93, -24.78, 10.62, -1.62, -15.37, 147.71, -14.13, 141.93, 8.07, 119.3, 23.74 ], + "hull": 25, + "edges": [ 8, 6, 6, 4, 4, 2, 2, 0, 0, 48, 46, 48, 46, 44, 44, 42, 42, 40, 40, 38, 38, 36, 36, 34, 32, 34, 50, 52, 52, 54, 54, 56, 40, 58, 58, 60, 8, 10, 20, 22, 22, 24, 62, 64, 64, 66, 66, 68, 8, 70, 70, 60, 68, 70, 58, 72, 72, 74, 74, 76, 76, 78, 24, 26, 26, 28, 58, 80, 80, 82, 82, 84, 84, 86, 86, 44, 70, 88, 88, 90, 90, 92, 92, 94, 94, 48, 80, 88, 88, 6, 82, 90, 90, 4, 84, 92, 92, 2, 86, 94, 94, 0, 56, 60, 10, 12, 12, 14, 14, 16, 28, 30, 30, 32, 26, 98, 98, 78, 30, 98, 24, 100, 100, 50, 98, 100, 22, 102, 102, 62, 100, 102, 16, 18, 18, 20, 102, 18 ], + "width": 82, + "height": 184 + } + }, + "front-thigh": { + "front-thigh": { "x": 42.48, "y": 4.45, "rotation": 84.87, "width": 45, "height": 112 } + }, + "front-upper-arm": { + "front-upper-arm": { "x": 28.31, "y": 7.37, "rotation": 97.9, "width": 46, "height": 97 } + }, + "goggles": { + "goggles": { + "type": "mesh", + "uvs": [ 0.53653, 0.04114, 0.72922, 0.16036, 0.91667, 0.33223, 0.97046, 0.31329, 1, 0.48053, 0.95756, 0.5733, 0.88825, 0.6328, 0.86878, 0.78962, 0.77404, 0.8675, 0.72628, 1, 0.60714, 0.93863, 0.49601, 0.88138, 0.41558, 0.75027, 0.32547, 0.70084, 0.2782, 0.58257, 0.1721, 0.63281, 0.17229, 0.75071, 0.10781, 0.79898, 0, 0.32304, 0, 0.12476, 0.07373, 0.07344, 0.15423, 0.10734, 0.23165, 0.13994, 0.30313, 0.02256, 0.34802, 0, 0.42979, 0.69183, 0.39476, 0.51042, 0.39488, 0.31512, 0.45878, 0.23198, 0.56501, 0.28109, 0.69961, 0.39216, 0.82039, 0.54204, 0.85738, 0.62343, 0.91107, 0.51407, 0.72639, 0.32147, 0.58764, 0.19609, 0.48075, 0.11269, 0.37823, 0.05501, 0.3287, 0.17866, 0.319, 0.305, 0.36036, 0.53799, 0.40327, 0.70072, 0.30059, 0.55838, 0.21957, 0.2815, 0.09963, 0.28943, 0.56863, 0.4368, 0.4911, 0.37156, 0.51185, 0.52093, 0.67018, 0.59304, 0.7619, 0.68575, 0.73296, 0.43355 ], + "triangles": [ 18, 44, 15, 21, 19, 20, 17, 18, 15, 44, 19, 21, 2, 3, 4, 18, 19, 44, 2, 33, 34, 33, 2, 4, 5, 33, 4, 5, 6, 33, 7, 32, 6, 31, 50, 33, 32, 31, 33, 6, 32, 33, 31, 49, 50, 49, 31, 32, 49, 32, 7, 8, 49, 7, 33, 50, 34, 17, 15, 16, 9, 48, 8, 49, 48, 50, 50, 48, 45, 47, 45, 48, 50, 45, 30, 45, 47, 46, 45, 46, 29, 30, 45, 29, 30, 29, 34, 30, 34, 50, 47, 26, 46, 25, 10, 11, 12, 25, 11, 41, 12, 42, 42, 44, 43, 43, 21, 22, 41, 40, 25, 41, 42, 40, 29, 35, 34, 40, 26, 25, 25, 26, 47, 37, 24, 0, 36, 37, 0, 42, 43, 39, 42, 39, 40, 28, 38, 36, 40, 39, 26, 28, 27, 38, 26, 39, 27, 37, 38, 23, 39, 43, 38, 38, 37, 36, 27, 39, 38, 43, 22, 38, 37, 23, 24, 22, 23, 38, 36, 0, 35, 28, 36, 35, 29, 28, 35, 27, 28, 46, 26, 27, 46, 35, 0, 1, 34, 35, 1, 12, 41, 25, 47, 10, 25, 44, 21, 43, 42, 14, 44, 14, 15, 44, 13, 14, 42, 12, 13, 42, 46, 28, 29, 47, 48, 10, 48, 9, 10, 49, 8, 48, 2, 34, 1 ], + "vertices": [ 2, 66, 61.88, 22.81, 0.832, 46, 172.09, 22.81, 0.168, 2, 66, 59.89, -31.19, 0.6855, 46, 170.1, -31.19, 0.3145, 2, 66, 49.2, -86.8, 0.32635, 46, 159.41, -86.8, 0.67365, 2, 66, 56.82, -99.01, 0.01217, 46, 167.03, -99.01, 0.98783, 1, 46, 143.4, -115.48, 1, 2, 66, 15, -110.14, 0.0041, 46, 125.21, -110.14, 0.9959, 2, 66, -0.32, -96.36, 0.07948, 46, 109.89, -96.36, 0.92052, 2, 66, -26.56, -100.19, 0.01905, 46, 83.65, -100.19, 0.98095, 2, 66, -46.96, -81.16, 0.4921, 46, 63.26, -81.16, 0.50791, 2, 66, -71.84, -76.69, 0.56923, 46, 38.37, -76.69, 0.43077, 2, 66, -72.54, -43.98, 0.74145, 46, 37.67, -43.98, 0.25855, 2, 66, -73.2, -13.47, 0.87929, 46, 37.01, -13.47, 0.12071, 2, 66, -59.63, 13.55, 0.864, 46, 50.58, 13.55, 0.136, 2, 66, -59.69, 38.45, 0.85289, 46, 50.52, 38.45, 0.14711, 2, 66, -45.26, 56.6, 0.74392, 46, 64.95, 56.6, 0.25608, 2, 66, -62.31, 79.96, 0.624, 46, 47.9, 79.96, 0.376, 2, 66, -80.76, 73.42, 0.616, 46, 29.45, 73.42, 0.384, 2, 66, -93.9, 86.64, 0.288, 46, 16.31, 86.64, 0.712, 1, 46, 81.51, 139.38, 1, 1, 46, 112.56, 150.3, 1, 2, 66, 16.76, 134.97, 0.02942, 46, 126.97, 134.97, 0.97058, 2, 66, 18.42, 113.28, 0.36147, 46, 128.63, 113.28, 0.63853, 2, 66, 20.02, 92.43, 0.7135, 46, 130.23, 92.43, 0.2865, 2, 66, 44.58, 81.29, 0.69603, 46, 154.79, 81.29, 0.30397, 2, 66, 52, 71.48, 0.848, 46, 162.21, 71.48, 0.152, 2, 66, -49.25, 13.27, 0.8, 46, 60.96, 13.27, 0.2, 2, 66, -23.88, 31.88, 0.896, 46, 86.33, 31.88, 0.104, 2, 66, 6.72, 42.6, 0.928, 46, 116.93, 42.6, 0.072, 2, 66, 25.26, 31.44, 0.8, 46, 135.47, 31.44, 0.2, 2, 66, 26.77, 2.59, 0.75, 46, 136.98, 2.59, 0.25, 2, 66, 21.02, -36.66, 0.54887, 46, 131.23, -36.66, 0.45113, 2, 66, 8.01, -74.65, 0.36029, 46, 118.22, -74.65, 0.63971, 2, 66, -1.52, -88.24, 0.1253, 46, 108.69, -88.24, 0.8747, 2, 66, 20.25, -95.44, 0.08687, 46, 130.46, -95.44, 0.91313, 2, 66, 34.42, -39.36, 0.72613, 46, 144.63, -39.36, 0.27387, 2, 66, 42.03, 1.7, 0.824, 46, 152.25, 1.7, 0.176, 2, 66, 45.85, 32.6, 0.856, 46, 156.06, 32.6, 0.144, 1, 66, 46.01, 61.02, 1, 1, 66, 22.35, 66.41, 1, 1, 66, 1.73, 61.84, 1, 2, 66, -31.17, 38.83, 0.928, 46, 79.04, 38.83, 0.072, 2, 66, -52.94, 19.31, 0.79073, 46, 57.27, 19.31, 0.20927, 2, 66, -39.54, 52.42, 0.912, 46, 70.67, 52.42, 0.088, 2, 66, -3.2, 87.61, 0.744, 46, 107.02, 87.61, 0.256, 2, 66, -14.82, 116.7, 0.6368, 46, 95.4, 116.7, 0.3632, 2, 66, 2.7, -6.87, 0.856, 46, 112.91, -6.87, 0.144, 2, 66, 6.21, 15.8, 0.744, 46, 116.42, 15.8, 0.256, 2, 66, -15.39, 2.47, 0.856, 46, 94.82, 2.47, 0.144, 2, 66, -12.98, -40.48, 0.72102, 46, 97.24, -40.48, 0.27898, 2, 66, -19.55, -68.16, 0.59162, 46, 90.66, -68.16, 0.40838, 2, 66, 17.44, -47.15, 0.53452, 46, 127.65, -47.15, 0.46548 ], + "hull": 25, + "edges": [ 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, 26, 24, 24, 22, 18, 16, 16, 14, 14, 12, 12, 10, 10, 8, 8, 6, 6, 4, 4, 2, 2, 0, 0, 48, 48, 46, 46, 44, 36, 38, 40, 38, 24, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 62, 64, 64, 12, 8, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78, 80, 80, 82, 82, 24, 24, 84, 84, 86, 86, 44, 40, 42, 42, 44, 42, 88, 88, 30, 58, 90, 90, 92, 92, 94, 18, 20, 20, 22, 94, 20, 18, 96, 96, 98, 60, 100, 100, 62, 98, 100 ], + "width": 261, + "height": 166 + } + }, + "gun": { + "gun": { "x": 77.3, "y": 16.4, "rotation": 60.83, "width": 210, "height": 203 } + }, + "head": { + "head": { + "type": "mesh", + "uvs": [ 0.75919, 0.06107, 0.88392, 0.17893, 0.90174, 0.30856, 0.94224, 0.1966, 1, 0.26584, 1, 0.422, 0.95864, 0.46993, 0.92118, 0.51333, 0.85957, 0.5347, 0.78388, 0.65605, 0.74384, 0.74838, 0.85116, 0.75151, 0.84828, 0.82564, 0.81781, 0.85367, 0.75599, 0.85906, 0.76237, 0.90468, 0.65875, 1, 0.38337, 1, 0.1858, 0.85404, 0.12742, 0.81091, 0.06025, 0.69209, 0, 0.58552, 0, 0.41021, 0.0853, 0.20692, 0.24243, 0.14504, 0.5, 0.1421, 0.50324, 0.07433, 0.41738, 0, 0.57614, 0, 0.85059, 0.36087, 0.73431, 0.43206, 0.68481, 0.31271, 0.72165, 0.16718, 0.55931, 0.04154, 0.44764, 0.22895, 0.23926, 0.26559, 0.71272, 0.44036, 0.56993, 0.383, 0.41678, 0.33511, 0.293, 0.31497, 0.70802, 0.44502, 0.56676, 0.38976, 0.41521, 0.34416, 0.28754, 0.33017, 0.88988, 0.50177, 0.30389, 0.73463, 0.2646, 0.65675, 0.21414, 0.61584, 0.14613, 0.62194, 0.10316, 0.66636, 0.10358, 0.72557, 0.14505, 0.79164, 0.20263, 0.81355, 0.27873, 0.80159, 0.34947, 0.7376, 0.23073, 0.57073, 0.08878, 0.60707, 0.29461, 0.8129, 0.73006, 0.87883, 0.69805, 0.87348, 0.66166, 0.79681, 0.22468, 0.69824, 0.14552, 0.67405 ], + "triangles": [ 50, 49, 62, 34, 25, 31, 39, 35, 34, 38, 39, 34, 37, 38, 34, 42, 39, 38, 43, 39, 42, 32, 2, 31, 31, 37, 34, 42, 38, 37, 41, 42, 37, 43, 22, 39, 30, 31, 29, 36, 37, 31, 30, 36, 31, 40, 41, 37, 36, 40, 37, 36, 30, 44, 55, 22, 43, 55, 48, 56, 47, 48, 55, 46, 55, 54, 42, 55, 43, 47, 55, 46, 62, 49, 48, 61, 47, 46, 62, 48, 47, 61, 62, 47, 46, 54, 45, 42, 41, 55, 61, 46, 45, 55, 41, 54, 61, 51, 50, 61, 50, 62, 60, 41, 40, 54, 41, 60, 53, 61, 45, 52, 51, 61, 57, 53, 45, 57, 45, 54, 53, 52, 61, 52, 19, 51, 57, 18, 52, 57, 52, 53, 17, 54, 60, 57, 54, 17, 18, 57, 17, 19, 50, 51, 33, 27, 28, 26, 27, 33, 0, 33, 28, 32, 33, 0, 32, 0, 1, 33, 25, 26, 33, 32, 25, 31, 25, 32, 2, 32, 1, 2, 3, 4, 29, 31, 2, 2, 4, 5, 29, 2, 5, 6, 29, 5, 30, 29, 6, 44, 30, 6, 18, 19, 52, 49, 56, 48, 34, 24, 25, 35, 23, 24, 35, 24, 34, 39, 22, 35, 22, 23, 35, 7, 44, 6, 8, 36, 44, 40, 36, 8, 8, 44, 7, 56, 21, 22, 55, 56, 22, 9, 40, 8, 20, 21, 56, 20, 56, 49, 9, 60, 40, 10, 60, 9, 20, 50, 19, 12, 10, 11, 13, 10, 12, 14, 60, 10, 13, 14, 10, 59, 60, 14, 58, 59, 14, 58, 14, 15, 16, 17, 60, 59, 16, 60, 15, 16, 59, 15, 59, 58, 20, 49, 50 ], + "vertices": [ 2, 50, 41.97, -41.8, 0.94074, 66, 165.41, -22.6, 0.05926, 4, 48, 73.47, 27.54, 0.26795, 50, -5.75, -51.71, 0.4738, 49, 112.99, -11.41, 0.12255, 66, 143.5, -66.13, 0.1357, 4, 48, 38.23, 10.99, 0.6831, 50, -41.01, -35.22, 0.07866, 49, 92.73, -44.66, 0.04872, 66, 108.65, -83.49, 0.18952, 2, 48, 73.35, 10.89, 0.8455, 66, 143.77, -82.78, 0.1545, 2, 48, 58.59, -10.38, 0.91607, 66, 129.5, -104.39, 0.08393, 3, 46, 195.82, -119.82, 0.104, 47, 75.49, -4.55, 0.09191, 48, 14.36, -24.8, 0.80409, 4, 46, 178.62, -113.98, 0.19022, 47, 59.82, -13.72, 0.33409, 48, -2.7, -18.57, 0.46643, 66, 68.41, -113.98, 0.00926, 4, 46, 163.06, -108.69, 0.18724, 47, 45.64, -22.03, 0.3133, 48, -18.14, -12.93, 0.47469, 66, 52.84, -108.69, 0.02477, 2, 46, 151.52, -95.05, 0.91122, 66, 41.31, -95.05, 0.08878, 2, 46, 110.61, -87.69, 0.70564, 66, 0.4, -87.69, 0.29436, 2, 46, 81.05, -86.58, 0.63951, 66, -29.16, -86.58, 0.36049, 2, 46, 89.82, -114.32, 0.57, 66, -20.39, -114.32, 0.43, 2, 46, 68.72, -120.91, 0.57, 66, -41.49, -120.91, 0.43, 2, 46, 58.1, -115.9, 0.57, 66, -52.11, -115.9, 0.43, 2, 46, 51.03, -100.63, 0.64242, 66, -59.18, -100.63, 0.35758, 2, 46, 38.79, -106.76, 0.81659, 66, -71.43, -106.76, 0.18341, 2, 46, 2.68, -89.7, 0.77801, 66, -107.53, -89.7, 0.22199, 2, 46, -22.07, -19.3, 0.823, 66, -132.28, -19.3, 0.177, 2, 46, 1.2, 45.63, 0.51204, 66, -109.01, 45.63, 0.48796, 2, 46, 8.07, 64.81, 0.60869, 66, -102.14, 64.81, 0.39131, 2, 46, 35.44, 93.73, 0.80009, 66, -74.77, 93.73, 0.19991, 2, 46, 59.98, 119.66, 0.93554, 66, -50.23, 119.66, 0.06446, 2, 46, 109.26, 136.99, 0.99895, 66, -0.95, 136.99, 0.00105, 1, 46, 174.07, 135.27, 1, 3, 46, 205.59, 101.22, 0.80778, 49, -16.84, 104.63, 0.15658, 66, 95.38, 101.22, 0.03564, 3, 50, 58.94, 30.5, 0.43491, 49, 38.36, 61.89, 0.28116, 66, 119.35, 35.65, 0.28393, 2, 50, 75.56, 19.01, 0.92164, 66, 138.68, 41.52, 0.07836, 1, 50, 106.7, 26.9, 1, 1, 50, 83.79, -9.51, 1, 5, 47, 44.51, 27.24, 0.15139, 48, 19.12, 19.33, 0.44847, 50, -46.82, -15.19, 0.05757, 49, 72.19, -48.24, 0.1149, 66, 89.35, -75.58, 0.22767, 3, 47, 7.42, 19.08, 0.37772, 49, 34.32, -45.24, 0.09918, 66, 58.9, -52.89, 0.52311, 2, 49, 45.94, -9.07, 0.4826, 66, 87.99, -28.45, 0.5174, 2, 50, 20.62, -16.35, 0.7435, 66, 132.21, -23.49, 0.2565, 2, 50, 75.74, 0.94, 0.97172, 66, 152.95, 30.42, 0.02828, 4, 46, 200.45, 40.46, 0.18809, 50, 44.6, 56.29, 0.05831, 49, 11.15, 50.46, 0.14366, 66, 90.24, 40.46, 0.60994, 2, 46, 171.41, 90.12, 0.48644, 66, 61.2, 90.12, 0.51356, 2, 46, 164.84, -48.18, 0.43217, 66, 54.62, -48.18, 0.56783, 4, 46, 168.13, -6.02, 0.01949, 47, -28.65, 49.02, 0.02229, 49, 8.54, -6.09, 0.12791, 66, 57.92, -6.02, 0.83031, 2, 46, 167.84, 37.87, 0.15, 66, 57.63, 37.87, 0.85, 2, 46, 162.36, 71.5, 0.24107, 66, 52.15, 71.5, 0.75893, 2, 46, 163.11, -47.44, 0.41951, 66, 52.9, -47.44, 0.58049, 2, 46, 165.94, -5.87, 0.16355, 66, 55.73, -5.87, 0.83645, 2, 46, 165.14, 37.38, 0.15, 66, 54.93, 37.38, 0.85, 2, 46, 157.6, 71.4, 0.21735, 66, 47.39, 71.4, 0.78265, 3, 46, 163.5, -99.54, 0.61812, 47, 39.01, -15.71, 0.30445, 66, 53.29, -99.54, 0.07744, 2, 46, 45.38, 27.24, 0.16741, 66, -64.83, 27.24, 0.83259, 2, 46, 63.74, 44.98, 0.15, 66, -46.47, 44.98, 0.85, 2, 46, 70.7, 61.92, 0.22175, 66, -39.51, 61.92, 0.77825, 2, 46, 62.88, 78.71, 0.38, 66, -47.34, 78.71, 0.62, 2, 46, 46.53, 85.3, 0.51, 66, -63.68, 85.3, 0.49, 2, 46, 29.92, 79.34, 0.388, 66, -80.29, 79.34, 0.612, 2, 46, 15.08, 62.21, 0.38, 66, -95.13, 62.21, 0.62, 2, 46, 14.09, 45.32, 0.41, 66, -96.12, 45.32, 0.59, 2, 46, 24.3, 27.06, 0.192, 66, -85.91, 27.06, 0.808, 1, 66, -61.57, 15.3, 1, 2, 46, 84.87, 62.14, 0.16757, 66, -25.34, 62.14, 0.83243, 2, 46, 61.9, 94.84, 0.68145, 66, -48.31, 94.84, 0.31855, 2, 46, 22.54, 21.88, 0.16, 66, -87.67, 21.88, 0.84, 2, 46, 43.15, -95.95, 0.73445, 66, -67.06, -95.95, 0.26555, 2, 46, 41.77, -87.24, 0.67858, 66, -68.44, -87.24, 0.32142, 2, 46, 60.05, -70.36, 0.50195, 66, -50.16, -70.36, 0.49805, 2, 46, 48.49, 51.09, 0.25, 66, -61.72, 51.09, 0.75, 2, 46, 48.17, 73.71, 0.15634, 66, -62.04, 73.71, 0.84366 ], + "hull": 29, + "edges": [ 10, 8, 8, 6, 6, 4, 4, 2, 2, 0, 0, 56, 54, 56, 54, 52, 52, 50, 50, 48, 48, 46, 46, 44, 42, 44, 32, 34, 4, 58, 58, 60, 62, 64, 64, 66, 66, 54, 50, 68, 68, 70, 70, 44, 60, 72, 62, 74, 72, 74, 74, 76, 76, 78, 78, 44, 16, 80, 80, 82, 82, 84, 84, 86, 86, 44, 14, 88, 88, 72, 14, 16, 10, 12, 12, 14, 12, 60, 90, 92, 92, 94, 94, 96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 90, 108, 110, 110, 112, 38, 40, 40, 42, 112, 40, 34, 36, 36, 38, 36, 114, 114, 108, 30, 32, 30, 28, 24, 26, 28, 26, 22, 24, 22, 20, 20, 18, 18, 16, 28, 116, 116, 118, 118, 120, 120, 20 ], + "width": 271, + "height": 298 + } + }, + "head-bb": { + "head": { + "type": "boundingbox", + "vertexCount": 6, + "vertices": [ -19.14, -70.3, 40.8, -118.08, 257.78, -115.62, 285.17, 57.18, 120.77, 164.95, -5.07, 76.95 ] + } + }, + "hoverboard-board": { + "hoverboard-board": { + "type": "mesh", + "uvs": [ 0.13865, 0.56624, 0.11428, 0.51461, 0.07619, 0.52107, 0.02364, 0.52998, 0.01281, 0.53182, 0, 0.37979, 0, 0.2206, 0.00519, 0.10825, 0.01038, 0.10726, 0.03834, 0.10194, 0.05091, 0, 0.08326, 0, 0.10933, 0.04206, 0.1382, 0.08865, 0.18916, 0.24067, 0.22234, 0.4063, 0.23886, 0.44063, 0.83412, 0.44034, 0.88444, 0.38296, 0.92591, 0.32639, 0.95996, 0.28841, 0.98612, 0.28542, 1, 0.38675, 0.99494, 0.47104, 0.97883, 0.53251, 0.94409, 0.62135, 0.90206, 0.69492, 0.86569, 0.71094, 0.82822, 0.70791, 0.81286, 0.77127, 0.62931, 0.77266, 0.61364, 0.70645, 0.47166, 0.70664, 0.45901, 0.77827, 0.27747, 0.76986, 0.2658, 0.70372, 0.24976, 0.71381, 0.24601, 0.77827, 0.23042, 0.84931, 0.20926, 0.90956, 0.17299, 1, 0.15077, 0.99967, 0.12906, 0.90192, 0.10369, 0.73693, 0.10198, 0.62482, 0.09131, 0.47272, 0.09133, 0.41325, 0.15082, 0.41868, 0.21991, 0.51856, 0.06331, 0.10816, 0.08383, 0.21696, 0.08905, 0.37532, 0.15903, 0.58726, 0.17538, 0.65706, 0.20118, 0.8029, 0.17918, 0.55644, 0.22166, 0.5802, 0.86259, 0.57962, 0.92346, 0.48534, 0.96691, 0.36881, 0.0945, 0.13259, 0.12688, 0.17831, 0.15986, 0.24682, 0.18036, 0.31268, 0.20607, 0.4235, 0.16074, 0.85403, 0.13624, 0.70122, 0.12096, 0.64049, 0.02396, 0.21811, 0.02732, 0.37839, 0.02557, 0.4972, 0.14476, 0.45736, 0.18019, 0.51689, 0.19692, 0.56636 ], + "triangles": [ 10, 11, 12, 9, 10, 12, 49, 9, 12, 60, 49, 12, 13, 60, 12, 61, 60, 13, 50, 49, 60, 50, 60, 61, 68, 8, 9, 68, 9, 49, 68, 49, 50, 7, 8, 68, 6, 7, 68, 61, 13, 14, 62, 61, 14, 50, 61, 62, 63, 62, 14, 59, 20, 21, 19, 20, 59, 51, 50, 62, 51, 62, 63, 51, 69, 68, 51, 68, 50, 6, 68, 69, 5, 6, 69, 18, 19, 59, 15, 63, 14, 59, 21, 22, 47, 51, 63, 47, 46, 51, 47, 63, 64, 15, 64, 63, 64, 15, 16, 71, 46, 47, 23, 59, 22, 69, 51, 70, 45, 46, 71, 70, 51, 2, 58, 18, 59, 58, 59, 23, 17, 18, 58, 70, 5, 69, 2, 51, 46, 1, 45, 71, 47, 48, 71, 47, 64, 48, 48, 72, 71, 1, 71, 72, 16, 48, 64, 45, 2, 46, 2, 45, 1, 70, 4, 5, 3, 70, 2, 3, 4, 70, 24, 58, 23, 72, 0, 1, 73, 55, 72, 55, 0, 72, 48, 73, 72, 57, 17, 58, 25, 57, 58, 56, 48, 16, 73, 48, 56, 56, 16, 17, 56, 17, 57, 52, 0, 55, 24, 25, 58, 44, 0, 52, 67, 44, 52, 52, 56, 53, 73, 52, 55, 56, 52, 73, 67, 52, 53, 26, 57, 25, 66, 67, 53, 56, 32, 35, 53, 56, 35, 56, 57, 32, 28, 31, 57, 57, 31, 32, 57, 27, 28, 26, 27, 57, 36, 53, 35, 43, 44, 67, 43, 67, 66, 34, 35, 32, 29, 31, 28, 30, 31, 29, 53, 54, 66, 53, 36, 54, 33, 34, 32, 37, 54, 36, 65, 43, 66, 38, 54, 37, 54, 65, 66, 39, 65, 54, 42, 43, 65, 38, 39, 54, 40, 42, 65, 40, 41, 42, 65, 39, 40 ], + "vertices": [ -189.36, 15.62, -201.35, 23.47, -220.09, 22.49, -245.95, 21.13, -251.28, 20.86, -257.58, 43.96, -257.57, 68.16, -255.02, 85.24, -252.47, 85.39, -238.71, 86.2, -232.52, 101.69, -216.61, 101.69, -203.78, 95.3, -189.58, 88.21, -164.51, 65.1, -148.19, 39.93, -140.06, 34.71, 152.82, 34.73, 177.57, 43.45, 197.97, 52.05, 214.72, 57.82, 227.6, 58.27, 234.42, 42.87, 231.94, 30.06, 224.01, 20.72, 206.91, 7.21, 186.23, -3.97, 168.34, -6.4, 149.9, -5.94, 142.35, -15.57, 52.04, -15.77, 44.33, -5.71, -25.52, -5.73, -31.75, -16.62, -121.07, -15.34, -126.81, -5.28, -134.7, -6.81, -136.54, -16.61, -144.22, -27.41, -154.63, -36.57, -172.47, -50.31, -183.41, -50.26, -194.09, -35.4, -206.56, -10.32, -207.4, 6.72, -212.65, 29.84, -212.64, 38.88, -183.37, 38.05, -149.38, 22.86, -226.43, 85.25, -216.33, 68.71, -213.76, 44.64, -179.34, 12.42, -171.29, 1.81, -158.6, -20.36, -169.42, 17.11, -148.52, 13.49, 166.82, 13.56, 196.76, 27.89, 218.14, 45.6, -211.08, 81.54, -195.15, 74.59, -178.93, 64.17, -168.84, 54.16, -156.19, 37.31, -178.5, -28.13, -190.55, -4.9, -198.07, 4.33, -245.79, 68.54, -244.14, 44.18, -245, 26.12, -186.36, 32.17, -168.92, 23.12, -160.69, 15.6 ], + "hull": 45, + "edges": [ 0, 2, 8, 10, 10, 12, 12, 14, 18, 20, 20, 22, 26, 28, 28, 30, 30, 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46, 48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62, 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 80, 82, 82, 84, 84, 86, 86, 88, 0, 88, 2, 90, 90, 92, 92, 94, 94, 96, 96, 32, 18, 98, 98, 100, 100, 102, 2, 4, 102, 4, 92, 102, 0, 104, 104, 106, 106, 108, 78, 80, 108, 78, 74, 76, 76, 78, 62, 56, 64, 70, 0, 110, 112, 114, 114, 116, 116, 118, 118, 42, 50, 116, 114, 34, 98, 120, 120, 122, 22, 24, 24, 26, 120, 24, 122, 124, 124, 126, 126, 128, 128, 96, 80, 130, 130, 132, 132, 134, 134, 88, 14, 16, 16, 18, 136, 16, 136, 138, 138, 140, 4, 6, 6, 8, 140, 6, 96, 112, 92, 142, 142, 144, 110, 146, 146, 112, 144, 146 ], + "width": 492, + "height": 152 + } + }, + "hoverboard-thruster-front": { + "hoverboard-thruster": { "x": 0.02, "y": -7.08, "rotation": 0.17, "width": 60, "height": 64 } + }, + "hoverboard-thruster-rear": { + "hoverboard-thruster": { "x": 1.1, "y": -6.29, "rotation": 0.17, "width": 60, "height": 64 } + }, + "hoverglow-front": { + "hoverglow-small": { + "x": 2.13, + "y": -2, + "scaleX": 0.303, + "scaleY": 0.495, + "rotation": 0.15, + "width": 274, + "height": 75 + } + }, + "hoverglow-rear": { + "hoverglow-small": { + "x": 1.39, + "y": -2.09, + "scaleX": 0.303, + "scaleY": 0.495, + "rotation": 0.61, + "width": 274, + "height": 75 + } + }, + "mouth": { + "mouth-grind": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 66, -98.93, -85.88, 0.22, 46, 11.28, -85.88, 0.78, 2, 66, -129.77, 1.84, 0.6, 46, -19.56, 1.84, 0.4, 2, 66, -74.12, 21.41, 0.6, 46, 36.09, 21.41, 0.4, 2, 66, -43.28, -66.32, 0.4, 46, 66.93, -66.32, 0.6 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 93, + "height": 59 + }, + "mouth-oooo": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 46, 11.28, -85.89, 0.22, 66, -98.93, -85.89, 0.78, 2, 46, -19.56, 1.85, 0.6, 66, -129.78, 1.85, 0.4, 2, 46, 36.1, 21.42, 0.6, 66, -74.12, 21.42, 0.4, 2, 46, 66.94, -66.32, 0.4, 66, -43.27, -66.32, 0.6 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 93, + "height": 59 + }, + "mouth-smile": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 66, -98.93, -85.89, 0.21075, 46, 11.28, -85.89, 0.78925, 2, 66, -129.77, 1.85, 0.6, 46, -19.56, 1.85, 0.4, 2, 66, -74.11, 21.42, 0.6, 46, 36.1, 21.42, 0.4, 2, 66, -43.27, -66.32, 0.40772, 46, 66.94, -66.32, 0.59228 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 93, + "height": 59 + } + }, + "muzzle": { + "muzzle01": { + "x": 151.97, + "y": 5.81, + "scaleX": 3.7361, + "scaleY": 3.7361, + "rotation": 0.15, + "width": 133, + "height": 79 + }, + "muzzle02": { + "x": 187.25, + "y": 5.9, + "scaleX": 4.0623, + "scaleY": 4.0623, + "rotation": 0.15, + "width": 135, + "height": 84 + }, + "muzzle03": { + "x": 231.96, + "y": 6.02, + "scaleX": 4.1325, + "scaleY": 4.1325, + "rotation": 0.15, + "width": 166, + "height": 106 + }, + "muzzle04": { + "x": 231.96, + "y": 6.02, + "scaleX": 4.0046, + "scaleY": 4.0046, + "rotation": 0.15, + "width": 149, + "height": 90 + }, + "muzzle05": { + "x": 293.8, + "y": 6.19, + "scaleX": 4.4673, + "scaleY": 4.4673, + "rotation": 0.15, + "width": 135, + "height": 75 + } + }, + "muzzle-glow": { + "muzzle-glow": { "width": 50, "height": 50 } + }, + "muzzle-ring": { + "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 } + }, + "muzzle-ring2": { + "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 } + }, + "muzzle-ring3": { + "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 } + }, + "muzzle-ring4": { + "muzzle-ring": { "x": -1.3, "y": 0.32, "scaleX": 0.3147, "scaleY": 0.3147, "width": 49, "height": 209 } + }, + "neck": { + "neck": { "x": 9.77, "y": -3.01, "rotation": -55.22, "width": 36, "height": 41 } + }, + "portal-bg": { + "portal-bg": { "x": -3.1, "y": 7.25, "scaleX": 1.0492, "scaleY": 1.0492, "width": 266, "height": 266 } + }, + "portal-flare1": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare2": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare3": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare4": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare5": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare6": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare7": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare8": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare9": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-flare10": { + "portal-flare1": { "width": 111, "height": 60 }, + "portal-flare2": { "width": 114, "height": 61 }, + "portal-flare3": { "width": 115, "height": 59 } + }, + "portal-shade": { + "portal-shade": { "width": 266, "height": 266 } + }, + "portal-streaks1": { + "portal-streaks1": { "scaleX": 0.9774, "scaleY": 0.9774, "width": 252, "height": 256 } + }, + "portal-streaks2": { + "portal-streaks2": { "x": -1.64, "y": 2.79, "width": 250, "height": 249 } + }, + "rear-bracer": { + "rear-bracer": { "x": 11.15, "y": -2.2, "rotation": 66.17, "width": 56, "height": 72 } + }, + "rear-foot": { + "rear-foot": { + "type": "mesh", + "uvs": [ 0.48368, 0.1387, 0.51991, 0.21424, 0.551, 0.27907, 0.58838, 0.29816, 0.63489, 0.32191, 0.77342, 0.39267, 1, 0.73347, 1, 1, 0.54831, 0.99883, 0.31161, 1, 0, 1, 0, 0.41397, 0.13631, 0, 0.41717, 0 ], + "triangles": [ 8, 3, 4, 8, 4, 5, 8, 5, 6, 8, 6, 7, 11, 1, 10, 3, 9, 2, 2, 10, 1, 12, 13, 0, 0, 11, 12, 1, 11, 0, 2, 9, 10, 3, 8, 9 ], + "vertices": [ 2, 8, 10.45, 29.41, 0.90802, 9, -6.74, 49.62, 0.09198, 2, 8, 16.56, 29.27, 0.84259, 9, -2.65, 45.09, 0.15741, 2, 8, 21.8, 29.15, 0.69807, 9, 0.85, 41.2, 0.30193, 2, 8, 25.53, 31.43, 0.52955, 9, 5.08, 40.05, 0.47045, 2, 8, 30.18, 34.27, 0.39303, 9, 10.33, 38.62, 0.60697, 2, 8, 44.02, 42.73, 0.27525, 9, 25.98, 34.36, 0.72475, 2, 8, 76.47, 47.28, 0.21597, 9, 51.56, 13.9, 0.78403, 2, 8, 88.09, 36.29, 0.28719, 9, 51.55, -2.09, 0.71281, 2, 8, 52.94, -0.73, 0.47576, 9, 0.52, -1.98, 0.52424, 2, 8, 34.63, -20.23, 0.68757, 9, -26.23, -2.03, 0.31243, 2, 8, 10.44, -45.81, 0.84141, 9, -61.43, -2, 0.15859, 2, 8, -15.11, -21.64, 0.93283, 9, -61.4, 33.15, 0.06717, 1, 8, -22.57, 6.61, 1, 1, 8, -0.76, 29.67, 1 ], + "hull": 14, + "edges": [ 14, 12, 10, 12, 14, 16, 16, 18, 18, 20, 4, 18, 20, 22, 24, 26, 22, 24, 4, 2, 2, 20, 4, 6, 6, 16, 6, 8, 8, 10, 2, 0, 0, 26 ], + "width": 113, + "height": 60 + } + }, + "rear-shin": { + "rear-shin": { "x": 58.29, "y": -2.75, "rotation": 92.37, "width": 75, "height": 178 } + }, + "rear-thigh": { + "rear-thigh": { "x": 33.11, "y": -4.11, "rotation": 72.54, "width": 55, "height": 94 } + }, + "rear-upper-arm": { + "rear-upper-arm": { "x": 21.13, "y": 4.09, "rotation": 89.33, "width": 40, "height": 87 } + }, + "side-glow1": { + "hoverglow-small": { "x": 2.09, "scaleX": 0.2353, "scaleY": 0.4132, "width": 274, "height": 75 } + }, + "side-glow2": { + "hoverglow-small": { "x": 2.09, "scaleX": 0.2353, "scaleY": 0.4132, "width": 274, "height": 75 } + }, + "side-glow3": { + "hoverglow-small": { "x": 2.09, "scaleX": 0.3586, "scaleY": 0.6297, "width": 274, "height": 75 } + }, + "torso": { + "torso": { + "type": "mesh", + "uvs": [ 0.6251, 0.12672, 1, 0.26361, 1, 0.28871, 1, 0.66021, 1, 0.68245, 0.92324, 0.69259, 0.95116, 0.84965, 0.77124, 1, 0.49655, 1, 0.27181, 1, 0.13842, 0.77196, 0.09886, 0.6817, 0.05635, 0.58471, 0, 0.45614, 0, 0.33778, 0, 0.19436, 0.14463, 0, 0.27802, 0, 0.72525, 0.27835, 0.76091, 0.46216, 0.84888, 0.67963, 0.68257, 0.63249, 0.53986, 0.3847, 0.25443, 0.3217, 0.30063, 0.55174, 0.39553, 0.79507, 0.26389, 0.17007, 0.5241, 0.18674, 0.71492, 0.76655, 0.82151, 0.72956, 0.27626, 0.4304, 0.62327, 0.52952, 0.3455, 0.66679, 0.53243, 0.2914 ], + "triangles": [ 18, 1, 2, 19, 2, 3, 18, 0, 1, 23, 15, 26, 27, 26, 16, 14, 15, 23, 15, 16, 26, 17, 27, 16, 13, 14, 23, 0, 27, 17, 13, 23, 30, 11, 12, 24, 21, 31, 19, 12, 13, 30, 24, 22, 31, 31, 22, 19, 12, 30, 24, 32, 24, 31, 24, 30, 22, 3, 20, 19, 32, 31, 21, 11, 24, 32, 4, 5, 3, 8, 28, 7, 7, 29, 6, 7, 28, 29, 9, 25, 8, 8, 25, 28, 9, 10, 25, 29, 5, 6, 10, 32, 25, 25, 21, 28, 25, 32, 21, 10, 11, 32, 28, 21, 29, 29, 20, 5, 29, 21, 20, 5, 20, 3, 20, 21, 19, 33, 26, 27, 22, 18, 19, 19, 18, 2, 33, 27, 18, 30, 23, 22, 22, 33, 18, 23, 33, 22, 33, 23, 26, 27, 0, 18 ], + "vertices": [ 2, 29, 44.59, -10.39, 0.88, 40, -17.65, 33.99, 0.12, 3, 28, 59.65, -45.08, 0.12189, 29, 17.13, -45.08, 0.26811, 40, 22.68, 15.82, 0.61, 3, 28, 55.15, -44.72, 0.1345, 29, 12.63, -44.72, 0.2555, 40, 23.43, 11.37, 0.61, 3, 27, 31.01, -39.45, 0.51133, 28, -11.51, -39.45, 0.30867, 40, 34.58, -54.57, 0.18, 3, 27, 27.01, -39.14, 0.53492, 28, -15.5, -39.14, 0.28508, 40, 35.25, -58.52, 0.18, 2, 27, 25.79, -31.5, 0.75532, 28, -16.73, -31.5, 0.24468, 1, 27, -2.61, -32, 1, 1, 27, -28.2, -12.29, 1, 1, 27, -26.08, 14.55, 1, 1, 27, -24.35, 36.5, 1, 2, 27, 17.6, 46.3, 0.8332, 28, -24.92, 46.3, 0.1668, 2, 27, 34.1, 48.89, 0.59943, 28, -8.42, 48.89, 0.40058, 3, 27, 51.83, 51.67, 0.29262, 28, 9.32, 51.67, 0.63181, 29, -33.2, 51.67, 0.07557, 3, 27, 75.34, 55.35, 0.06656, 28, 32.82, 55.35, 0.62298, 29, -9.7, 55.35, 0.31046, 2, 28, 54.06, 53.67, 0.37296, 29, 11.54, 53.67, 0.62704, 2, 28, 79.79, 51.64, 0.10373, 29, 37.27, 51.64, 0.89627, 1, 29, 71.04, 34.76, 1, 1, 29, 70.01, 21.72, 1, 1, 30, 36.74, 7.06, 1, 3, 30, 45.7, -24.98, 0.67, 28, 25.87, -18.9, 0.3012, 29, -16.65, -18.9, 0.0288, 2, 27, 28.69, -24.42, 0.77602, 28, -13.83, -24.42, 0.22398, 3, 30, 43.24, -56.49, 0.064, 27, 38.43, -8.84, 0.67897, 28, -4.09, -8.84, 0.25703, 3, 30, 22.02, -14.85, 0.29, 28, 41.48, 1.59, 0.53368, 29, -1.04, 1.59, 0.17632, 3, 30, -7.45, -8.33, 0.76, 28, 54.98, 28.59, 0.06693, 29, 12.46, 28.59, 0.17307, 3, 30, 3.91, -48.4, 0.25, 27, 55.87, 27.33, 0.15843, 28, 13.35, 27.33, 0.59157, 1, 27, 11.47, 21.51, 1, 2, 30, -11.09, 18.74, 0.416, 29, 39.6, 25.51, 0.584, 2, 30, 14.56, 20.03, 0.53, 29, 34.6, 0.33, 0.47, 1, 27, 14.12, -10.1, 1, 2, 27, 19.94, -21.03, 0.92029, 28, -22.58, -21.03, 0.07971, 3, 30, -2.08, -27.26, 0.29, 28, 35.31, 27.99, 0.49582, 29, -7.21, 27.99, 0.21418, 2, 30, 34.42, -39.19, 0.25, 28, 14.84, -4.5, 0.75, 2, 27, 34.87, 24.58, 0.67349, 28, -7.64, 24.58, 0.32651, 2, 30, 18.5, 1.59, 0.76, 29, 15.76, 1, 0.24 ], + "hull": 18, + "edges": [ 14, 12, 12, 10, 10, 8, 18, 20, 32, 34, 30, 32, 2, 4, 36, 4, 36, 38, 38, 40, 4, 6, 6, 8, 40, 6, 40, 42, 14, 16, 16, 18, 50, 16, 46, 52, 54, 36, 2, 0, 0, 34, 54, 0, 54, 32, 20, 50, 14, 56, 56, 42, 50, 56, 56, 58, 58, 40, 58, 10, 46, 60, 60, 48, 26, 60, 60, 44, 24, 26, 24, 48, 42, 62, 62, 44, 48, 62, 48, 64, 64, 50, 42, 64, 20, 22, 22, 24, 64, 22, 26, 28, 28, 30, 28, 46, 44, 66, 66, 54, 46, 66, 66, 36, 62, 38 ], + "width": 98, + "height": 180 + } + } + } + } +], +"events": { + "footstep": {} +}, +"animations": { + "aim": { + "slots": { + "crosshair": { + "attachment": [ + { "name": "crosshair" } + ] + } + }, + "bones": { + "front-fist": { + "rotate": [ + { "value": 36.08 } + ] + }, + "rear-bracer": { + "rotate": [ + { "value": -26.55 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { "value": 62.31 } + ] + }, + "front-bracer": { + "rotate": [ + { "value": 9.11 } + ] + }, + "gun": { + "rotate": [ + { "value": -0.31 } + ] + } + }, + "ik": { + "aim-ik": [ + { "mix": 0.995 } + ] + }, + "transform": { + "aim-front-arm-transform": [ + { "mixRotate": 0.784, "mixX": 0, "mixScaleX": 0, "mixShearY": 0 } + ], + "aim-head-transform": [ + { "mixRotate": 0.659, "mixX": 0, "mixScaleX": 0, "mixShearY": 0 } + ], + "aim-torso-transform": [ + { "mixRotate": 0.423, "mixX": 0, "mixScaleX": 0, "mixShearY": 0 } + ] + } + }, + "death": { + "slots": { + "eye": { + "attachment": [ + { "name": "eye-surprised" }, + { "time": 0.5333, "name": "eye-indifferent" }, + { "time": 2.2, "name": "eye-surprised" }, + { "time": 4.6, "name": "eye-indifferent" } + ] + }, + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + }, + "mouth": { + "attachment": [ + { "name": "mouth-oooo" }, + { "time": 0.5333, "name": "mouth-grind" }, + { "time": 1.4, "name": "mouth-oooo" }, + { "time": 2.1667, "name": "mouth-grind" }, + { "time": 4.5333, "name": "mouth-oooo" } + ] + } + }, + "bones": { + "head": { + "rotate": [ + { + "value": -2.83, + "curve": [ 0.015, -2.83, 0.036, 12.72 ] + }, + { + "time": 0.0667, + "value": 12.19, + "curve": [ 0.096, 11.68, 0.119, -1.14 ] + }, + { + "time": 0.1333, + "value": -6.86, + "curve": [ 0.149, -13.27, 0.21, -37.28 ] + }, + { + "time": 0.3, + "value": -36.86, + "curve": [ 0.354, -36.61, 0.412, -32.35 ] + }, + { + "time": 0.4667, + "value": -23.49, + "curve": [ 0.49, -19.87, 0.512, -3.29 ] + }, + { + "time": 0.5333, + "value": -3.24, + "curve": [ 0.56, -3.39, 0.614, -67.25 ] + }, + { + "time": 0.6333, + "value": -74.4, + "curve": [ 0.652, -81.58, 0.702, -88.94 ] + }, + { + "time": 0.7333, + "value": -88.93, + "curve": [ 0.805, -88.91, 0.838, -80.87 ] + }, + { + "time": 0.8667, + "value": -81.03, + "curve": [ 0.922, -81.32, 0.976, -85.29 ] + }, + { "time": 1, "value": -85.29, "curve": "stepped" }, + { + "time": 2.2333, + "value": -85.29, + "curve": [ 2.314, -85.29, 2.382, -68.06 ] + }, + { + "time": 2.4667, + "value": -63.48, + "curve": [ 2.57, -57.87, 2.916, -55.24 ] + }, + { + "time": 3.2, + "value": -55.1, + "curve": [ 3.447, -54.98, 4.135, -56.61 ] + }, + { + "time": 4.2667, + "value": -58.23, + "curve": [ 4.672, -63.24, 4.646, -82.69 ] + }, + { "time": 4.9333, "value": -85.29 } + ], + "scale": [ + { + "time": 0.4667, + "curve": [ 0.469, 1.005, 0.492, 1.065, 0.475, 1.018, 0.492, 0.94 ] + }, + { + "time": 0.5, + "x": 1.065, + "y": 0.94, + "curve": [ 0.517, 1.065, 0.541, 0.991, 0.517, 0.94, 0.542, 1.026 ] + }, + { + "time": 0.5667, + "x": 0.99, + "y": 1.025, + "curve": [ 0.593, 0.988, 0.609, 1.002, 0.595, 1.024, 0.607, 1.001 ] + }, + { "time": 0.6333 } + ] + }, + "neck": { + "rotate": [ + { + "value": -2.83, + "curve": [ 0.114, 1.33, 0.195, 4.13 ] + }, + { + "time": 0.2667, + "value": 4.13, + "curve": [ 0.351, 4.14, 0.444, -24.5 ] + }, + { + "time": 0.5, + "value": -24.69, + "curve": [ 0.571, -23.89, 0.55, 34.22 ] + }, + { + "time": 0.6667, + "value": 35.13, + "curve": [ 0.713, 34.81, 0.756, 22.76 ] + }, + { + "time": 0.8333, + "value": 22.82, + "curve": [ 0.868, 22.84, 0.916, 47.95 ] + }, + { "time": 0.9667, "value": 47.95, "curve": "stepped" }, + { + "time": 2.2333, + "value": 47.95, + "curve": [ 2.3, 47.95, 2.617, 18.72 ] + }, + { + "time": 2.6667, + "value": 18.51, + "curve": [ 3.172, 16.58, 4.06, 16.79 ] + }, + { + "time": 4.5333, + "value": 18.51, + "curve": [ 4.707, 19.13, 4.776, 41.11 ] + }, + { "time": 4.8, "value": 47.95 } + ] + }, + "torso": { + "rotate": [ + { + "value": -8.62, + "curve": [ 0.01, -16.71, 0.032, -33.6 ] + }, + { + "time": 0.0667, + "value": -33.37, + "curve": [ 0.182, -32.61, 0.298, 123.07 ] + }, + { + "time": 0.4667, + "value": 122.77, + "curve": [ 0.511, 122.69, 0.52, 100.2 ] + }, + { + "time": 0.5667, + "value": 88.96, + "curve": [ 0.588, 83.89, 0.667, 75.34 ] + }, + { + "time": 0.7, + "value": 75.34, + "curve": [ 0.767, 75.34, 0.9, 76.03 ] + }, + { "time": 0.9667, "value": 76.03 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -38.86, + "curve": [ 0.022, -40.38, 0.096, -41.92 ] + }, + { + "time": 0.1333, + "value": -41.92, + "curve": [ 0.176, -41.92, 0.216, -16.92 ] + }, + { + "time": 0.2333, + "value": -4.35, + "curve": [ 0.258, 13.69, 0.308, 60.35 ] + }, + { + "time": 0.4, + "value": 60.17, + "curve": [ 0.496, 59.98, 0.539, 33.63 ] + }, + { + "time": 0.5667, + "value": 23.06, + "curve": [ 0.595, 32.71, 0.675, 53.71 ] + }, + { + "time": 0.7333, + "value": 53.61, + "curve": [ 0.797, 53.51, 0.926, 30.98 ] + }, + { "time": 0.9333, "value": 19.57, "curve": "stepped" }, + { + "time": 1.9667, + "value": 19.57, + "curve": [ 2.245, 19.57, 2.702, 77.03 ] + }, + { + "time": 3.0667, + "value": 77.06, + "curve": [ 3.209, 77.33, 3.291, 67.99 ] + }, + { + "time": 3.4333, + "value": 67.96, + "curve": [ 3.608, 68.34, 3.729, 73.88 ] + }, + { + "time": 3.8333, + "value": 73.42, + "curve": [ 4.152, 73.91, 4.46, 71.98 ] + }, + { + "time": 4.6333, + "value": 64.77, + "curve": [ 4.688, 62.5, 4.847, 26.42 ] + }, + { "time": 4.8667, "value": 10.94 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": -44.7, + "curve": [ 0.033, -44.7, 0.12, 54.89 ] + }, + { + "time": 0.1333, + "value": 64.62, + "curve": [ 0.154, 79.18, 0.214, 79.42 ] + }, + { + "time": 0.2667, + "value": 63.4, + "curve": [ 0.293, 55.19, 0.332, 30.13 ] + }, + { + "time": 0.3667, + "value": 30.13, + "curve": [ 0.4, 30.13, 0.441, 39.87 ] + }, + { + "time": 0.4667, + "value": 55.13, + "curve": [ 0.488, 68.18, 0.52, 100.72 ] + }, + { + "time": 0.5333, + "value": 111.96, + "curve": [ 0.551, 126.88, 0.627, 185.97 ] + }, + { + "time": 0.6667, + "value": 185.97, + "curve": [ 0.692, 185.97, 0.736, 162.43 ] + }, + { + "time": 0.8, + "value": 158.01, + "curve": [ 0.9, 151.12, 1.017, 144.01 ] + }, + { "time": 1.1, "value": 144.01, "curve": "stepped" }, + { + "time": 2.3667, + "value": 144.01, + "curve": [ 2.492, 144.01, 2.742, 138.63 ] + }, + { + "time": 2.8667, + "value": 138.63, + "curve": [ 3.067, 138.63, 3.467, 138.63 ] + }, + { + "time": 3.6667, + "value": 138.63, + "curve": [ 3.883, 138.63, 4.317, 135.18 ] + }, + { + "time": 4.5333, + "value": 135.18, + "curve": [ 4.575, 135.18, 4.692, 131.59 ] + }, + { + "time": 4.7333, + "value": 131.59, + "curve": [ 4.758, 131.59, 4.517, 144.01 ] + }, + { "time": 4.8333, "value": 144.01 } + ], + "translate": [ + { + "time": 0.4667, + "curve": [ 0.517, 0, 0.617, -34.96, 0.517, 0, 0.617, -16.59 ] + }, + { "time": 0.6667, "x": -35.02, "y": -16.62 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 21.88, + "curve": [ 0.033, 21.88, 0.099, 20.44 ] + }, + { + "time": 0.1333, + "value": 9.43, + "curve": [ 0.164, -0.29, 0.162, -38.26 ] + }, + { + "time": 0.2, + "value": -38.05, + "curve": [ 0.24, -37.96, 0.228, -17.82 ] + }, + { + "time": 0.3333, + "value": -9.73, + "curve": [ 0.372, -6.76, 0.431, -0.74 ] + }, + { + "time": 0.4667, + "value": 6.47, + "curve": [ 0.489, 11.05, 0.503, 19.09 ] + }, + { + "time": 0.5333, + "value": 19.09, + "curve": [ 0.571, 19.09, 0.554, -42.67 ] + }, + { + "time": 0.6, + "value": -42.67, + "curve": [ 0.653, -42.67, 0.691, -13.8 ] + }, + { + "time": 0.7, + "value": -3.54, + "curve": [ 0.707, 3.8, 0.719, 24.94 ] + }, + { + "time": 0.8, + "value": 25.31, + "curve": [ 0.902, 24.75, 0.992, -0.34 ] + }, + { "time": 1, "value": -32.16, "curve": "stepped" }, + { + "time": 2.2333, + "value": -32.16, + "curve": [ 2.6, -32.16, 2.638, -5.3 ] + }, + { + "time": 2.7, + "value": -1.96, + "curve": [ 2.707, -1.56, 2.775, 1.67 ] + }, + { + "time": 2.8, + "value": 1.67, + "curve": [ 2.825, 1.67, 2.875, -0.39 ] + }, + { + "time": 2.9, + "value": -0.39, + "curve": [ 2.925, -0.39, 2.975, 0.26 ] + }, + { + "time": 3, + "value": 0.26, + "curve": [ 3.025, 0.26, 3.075, -1.81 ] + }, + { + "time": 3.1, + "value": -1.81, + "curve": [ 3.125, -1.81, 3.175, -0.52 ] + }, + { + "time": 3.2, + "value": -0.52, + "curve": [ 3.225, -0.52, 3.275, -2.41 ] + }, + { + "time": 3.3, + "value": -2.41, + "curve": [ 3.333, -2.41, 3.4, -0.38 ] + }, + { + "time": 3.4333, + "value": -0.38, + "curve": [ 3.467, -0.38, 3.533, -2.25 ] + }, + { + "time": 3.5667, + "value": -2.25, + "curve": [ 3.592, -2.25, 3.642, -0.33 ] + }, + { + "time": 3.6667, + "value": -0.33, + "curve": [ 3.7, -0.33, 3.767, -1.34 ] + }, + { + "time": 3.8, + "value": -1.34, + "curve": [ 3.825, -1.34, 3.862, -0.77 ] + }, + { + "time": 3.9, + "value": -0.77, + "curve": [ 3.942, -0.77, 3.991, -1.48 ] + }, + { + "time": 4, + "value": -1.87, + "curve": [ 4.167, -1.87, 4.5, -1.96 ] + }, + { + "time": 4.6667, + "value": -1.96, + "curve": [ 4.709, 18.05, 4.767, 34.55 ] + }, + { + "time": 4.8, + "value": 34.55, + "curve": [ 4.84, 34.24, 4.902, 12.03 ] + }, + { "time": 4.9333, "value": -18.75 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -2.33, + "curve": [ 0.019, 4.43, 0.069, 10.82 ] + }, + { + "time": 0.1, + "value": 10.6, + "curve": [ 0.148, 10.6, 0.123, -15.24 ] + }, + { + "time": 0.2, + "value": -15.35, + "curve": [ 0.266, -15.44, 0.316, -6.48 ] + }, + { + "time": 0.3333, + "value": -3.9, + "curve": [ 0.362, 0.43, 0.479, 22.36 ] + }, + { + "time": 0.5667, + "value": 22.01, + "curve": [ 0.61, 21.84, 0.627, 12.85 ] + }, + { + "time": 0.6333, + "value": 9.05, + "curve": [ 0.643, 2.77, 0.622, -39.43 ] + }, + { + "time": 0.7, + "value": -39.5, + "curve": [ 0.773, -39.57, 0.814, 14.77 ] + }, + { + "time": 0.8667, + "value": 14.81, + "curve": [ 0.965, 14.88, 1.1, 5.64 ] + }, + { "time": 1.1, "value": -6.08, "curve": "stepped" }, + { + "time": 2.2333, + "value": -6.08, + "curve": [ 2.307, -6.08, 2.427, -25.89 ] + }, + { + "time": 2.5333, + "value": -22.42, + "curve": [ 2.598, -20.38, 2.657, 5.73 ] + }, + { + "time": 2.7, + "value": 5.73, + "curve": [ 2.77, 5.73, 2.851, -5.38 ] + }, + { + "time": 2.9333, + "value": -5.38, + "curve": [ 3.008, -5.38, 3.087, -4.54 ] + }, + { + "time": 3.1667, + "value": -4.17, + "curve": [ 3.223, -3.91, 4.486, 5.73 ] + }, + { + "time": 4.6667, + "value": 5.73, + "curve": [ 4.733, 5.73, 4.886, -2.47 ] + }, + { "time": 4.9333, "value": -6.52 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": 10.36, + "curve": [ 0.033, 10.36, 0.1, -32.89 ] + }, + { + "time": 0.1333, + "value": -32.89, + "curve": [ 0.183, -32.89, 0.283, -4.45 ] + }, + { + "time": 0.3333, + "value": -4.45, + "curve": [ 0.367, -4.45, 0.438, -6.86 ] + }, + { + "time": 0.4667, + "value": -8.99, + "curve": [ 0.529, -13.62, 0.605, -20.58 ] + }, + { + "time": 0.6333, + "value": -23.2, + "curve": [ 0.708, -30.18, 0.758, -35.56 ] + }, + { + "time": 0.8, + "value": -35.56, + "curve": [ 0.875, -35.56, 1.025, -23.2 ] + }, + { "time": 1.1, "value": -23.2 } + ] + }, + "gun": { + "rotate": [ + { + "value": -2.79, + "curve": [ 0.033, -2.79, 0.12, -7.22 ] + }, + { + "time": 0.1333, + "value": -8.52, + "curve": [ 0.168, -11.87, 0.29, -23.71 ] + }, + { + "time": 0.3333, + "value": -26.24, + "curve": [ 0.369, -28.31, 0.436, -29.75 ] + }, + { + "time": 0.5, + "value": -29.66, + "curve": [ 0.552, -29.58, 0.611, -25.47 ] + }, + { + "time": 0.6333, + "value": -22.68, + "curve": [ 0.656, -19.76, 0.68, -10.02 ] + }, + { + "time": 0.7, + "value": -6.49, + "curve": [ 0.722, -2.6, 0.75, -1.22 ] + }, + { + "time": 0.7667, + "value": -1.35, + "curve": [ 0.792, -1.55, 0.842, -19.74 ] + }, + { "time": 0.8667, "value": -19.8 } + ] + }, + "hip": { + "translate": [ + { + "curve": [ 0.098, -42.62, 0.166, -79.85, 0.029, 84.97, 0.109, 155.93 ] + }, + { + "time": 0.2667, + "x": -133.79, + "y": 152.44, + "curve": [ 0.361, -184.63, 0.392, -203.69, 0.42, 149.12, 0.467, -15.7 ] + }, + { + "time": 0.4667, + "x": -230.02, + "y": -113.87, + "curve": [ 0.523, -249.86, 0.565, -261.7, 0.473, -133.1, 0.583, -203.43 ] + }, + { + "time": 0.6, + "x": -268.57, + "y": -203.43, + "curve": [ 0.663, -280.98, 0.816, -290.05, 0.708, -203.43, 0.892, -203.5 ] + }, + { "time": 1, "x": -290.42, "y": -203.5 } + ] + }, + "front-thigh": { + "rotate": [ + { + "curve": [ 0.06, 1.02, 0.151, 45.23 ] + }, + { + "time": 0.1667, + "value": 54.01, + "curve": [ 0.19, 66.85, 0.358, 169.85 ] + }, + { + "time": 0.5, + "value": 169.51, + "curve": [ 0.628, 169.85, 0.692, 108.85 ] + }, + { + "time": 0.7, + "value": 97.74, + "curve": [ 0.723, 102.6, 0.805, 111.6 ] + }, + { + "time": 0.8667, + "value": 111.69, + "curve": [ 0.899, 111.83, 1.015, 109.15 ] + }, + { "time": 1.0667, "value": 95.8 } + ] + }, + "front-shin": { + "rotate": [ + { + "curve": [ 0.086, -0.02, 0.191, -24.25 ] + }, + { + "time": 0.2, + "value": -26.5, + "curve": [ 0.214, -29.92, 0.249, -40.51 ] + }, + { + "time": 0.3333, + "value": -40.57, + "curve": [ 0.431, -40.7, 0.459, -11.34 ] + }, + { + "time": 0.4667, + "value": -8.71, + "curve": [ 0.477, -5.16, 0.524, 17.13 ] + }, + { + "time": 0.6, + "value": 16.98, + "curve": [ 0.632, 17.09, 0.625, 2.76 ] + }, + { + "time": 0.6333, + "value": 2.76, + "curve": [ 0.648, 2.76, 0.653, 2.75 ] + }, + { + "time": 0.6667, + "value": 2.59, + "curve": [ 0.678, 2.39, 0.733, 2.53 ] + }, + { + "time": 0.7333, + "value": -9.43, + "curve": [ 0.745, -2.48, 0.782, 3.12 ] + }, + { + "time": 0.8, + "value": 4.28, + "curve": [ 0.832, 6.32, 0.895, 8.46 ] + }, + { + "time": 0.9333, + "value": 8.49, + "curve": [ 0.986, 8.53, 1.051, 6.38 ] + }, + { + "time": 1.0667, + "value": 2.28, + "curve": [ 1.078, 4.17, 1.103, 5.86 ] + }, + { + "time": 1.1333, + "value": 5.88, + "curve": [ 1.191, 5.93, 1.209, 4.56 ] + }, + { "time": 1.2333, "value": 2.52 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "curve": [ 0.033, 0, 0.12, 50.26 ] + }, + { + "time": 0.1333, + "value": 57.3, + "curve": [ 0.164, 73.34, 0.274, 147.18 ] + }, + { + "time": 0.3333, + "value": 147.1, + "curve": [ 0.475, 146.45, 0.583, 95.72 ] + }, + { + "time": 0.6, + "value": 79.66, + "curve": [ 0.62, 94.74, 0.732, 103.15 ] + }, + { + "time": 0.7667, + "value": 103.02, + "curve": [ 0.812, 102.85, 0.897, 95.75 ] + }, + { "time": 0.9333, "value": 83.01 } + ] + }, + "rear-shin": { + "rotate": [ + { + "curve": [ 0.021, -16.65, 0.091, -54.82 ] + }, + { + "time": 0.1667, + "value": -55.29, + "curve": [ 0.187, -55.42, 0.213, -52.52 ] + }, + { + "time": 0.2333, + "value": -45.98, + "curve": [ 0.242, -43.1, 0.311, -12.73 ] + }, + { + "time": 0.3333, + "value": -6.32, + "curve": [ 0.356, 0.13, 0.467, 24.5 ] + }, + { + "time": 0.5, + "value": 24.5, + "curve": [ 0.543, 24.5, 0.56, 3.78 ] + }, + { + "time": 0.5667, + "value": -3.53, + "curve": [ 0.585, 3.86, 0.659, 16.63 ] + }, + { + "time": 0.7, + "value": 16.56, + "curve": [ 0.782, 16.43, 0.896, 8.44 ] + }, + { + "time": 0.9333, + "value": 4.04, + "curve": [ 0.956, 6.84, 1.008, 8.41 ] + }, + { + "time": 1.0333, + "value": 8.41, + "curve": [ 1.067, 8.41, 1.122, 8.14 ] + }, + { "time": 1.1667, "value": 5.8 } + ] + }, + "rear-foot": { + "rotate": [ + { + "value": -0.28, + "curve": [ 0.033, -0.28, 0.256, -66.71 ] + }, + { + "time": 0.3667, + "value": -66.84, + "curve": [ 0.418, -66.91, 0.499, -21.79 ] + }, + { + "time": 0.6, + "value": -21.52, + "curve": [ 0.652, -21.38, 0.665, -53.96 ] + }, + { + "time": 0.7, + "value": -54.26, + "curve": [ 0.757, -53.96, 0.843, -2.07 ] + }, + { + "time": 0.9333, + "value": -1.47, + "curve": [ 0.968, -2.07, 0.975, -19.96 ] + }, + { + "time": 1, + "value": -19.96, + "curve": [ 1.025, -19.96, 1.075, -12.42 ] + }, + { + "time": 1.1, + "value": -12.42, + "curve": [ 1.133, -12.42, 1.2, -18.34 ] + }, + { "time": 1.2333, "value": -18.34 } + ] + }, + "front-foot": { + "rotate": [ + { + "curve": [ 0.008, -11.33, 0.108, -57.71 ] + }, + { + "time": 0.1333, + "value": -57.71, + "curve": [ 0.175, -57.71, 0.229, 19.73 ] + }, + { + "time": 0.3, + "value": 19.34, + "curve": [ 0.354, 19.34, 0.4, -57.76 ] + }, + { + "time": 0.4333, + "value": -57.76, + "curve": [ 0.458, -57.76, 0.511, -3.56 ] + }, + { + "time": 0.5333, + "value": 3.7, + "curve": [ 0.563, 13.29, 0.633, 15.79 ] + }, + { + "time": 0.6667, + "value": 15.79, + "curve": [ 0.7, 15.79, 0.767, -48.75 ] + }, + { + "time": 0.8, + "value": -48.75, + "curve": [ 0.842, -48.75, 0.925, 4.7 ] + }, + { + "time": 0.9667, + "value": 4.7, + "curve": [ 1, 4.7, 1.067, -22.9 ] + }, + { + "time": 1.1, + "value": -22.9, + "curve": [ 1.142, -22.9, 1.225, -13.28 ] + }, + { "time": 1.2667, "value": -13.28 } + ] + }, + "rear-foot-target": { + "rotate": [ + { "value": -0.28 } + ] + }, + "front-foot-tip": { + "rotate": [ + { + "value": -0.28, + "curve": [ 0.008, -0.28, 0.003, -66.62 ] + }, + { + "time": 0.0667, + "value": -65.75, + "curve": [ 0.166, -64.42, 0.234, 14.35 ] + }, + { + "time": 0.2667, + "value": 38.25, + "curve": [ 0.294, 57.91, 0.392, 89.79 ] + }, + { + "time": 0.4667, + "value": 90.73, + "curve": [ 0.483, 90.73, 0.55, 177.66 ] + }, + { + "time": 0.5667, + "value": 177.66, + "curve": [ 0.733, 176.24, 0.75, 11.35 ] + }, + { + "time": 0.8, + "value": 11.35, + "curve": [ 0.886, 12.29, 0.911, 47.88 ] + }, + { + "time": 0.9333, + "value": 56.77, + "curve": [ 0.967, 70.59, 1.05, 86.46 ] + }, + { + "time": 1.1, + "value": 86.46, + "curve": [ 1.187, 86.46, 1.214, 66.44 ] + }, + { "time": 1.3333, "value": 64.55 } + ] + }, + "back-foot-tip": { + "rotate": [ + { + "value": -0.28, + "curve": [ 0, -7.97, 0.027, -18.69 ] + }, + { + "time": 0.0667, + "value": -19, + "curve": [ 0.166, -19.3, 0.208, 15.58 ] + }, + { + "time": 0.2667, + "value": 45.95, + "curve": [ 0.306, 66.24, 0.378, 99.08 ] + }, + { + "time": 0.4333, + "value": 99.08, + "curve": [ 0.497, 98.62, 0.488, -1.2 ] + }, + { + "time": 0.5667, + "value": -1.32, + "curve": [ 0.637, -0.84, 0.687, 94.41 ] + }, + { + "time": 0.7333, + "value": 94.33, + "curve": [ 0.832, 94.16, 0.895, 29.6 ] + }, + { + "time": 0.9667, + "value": 28.67, + "curve": [ 1.026, 28.67, 1.045, 53.14 ] + }, + { "time": 1.1, "value": 53.38 } + ] + }, + "hair4": { + "rotate": [ + { + "curve": [ 0.011, 4.5, 0.05, 11.42 ] + }, + { + "time": 0.0667, + "value": 11.42, + "curve": [ 0.1, 11.42, 0.136, -5.92 ] + }, + { + "time": 0.1667, + "value": -10.54, + "curve": [ 0.206, -16.51, 0.327, -22 ] + }, + { + "time": 0.3667, + "value": -24.47, + "curve": [ 0.413, -27.37, 0.467, -43.99 ] + }, + { + "time": 0.5, + "value": -43.99, + "curve": [ 0.533, -43.99, 0.552, 12.12 ] + }, + { + "time": 0.6333, + "value": 11.85, + "curve": [ 0.714, 11.59, 0.758, -34.13 ] + }, + { + "time": 0.8, + "value": -34.13, + "curve": [ 0.858, -34.13, 1.015, -12.47 ] + }, + { + "time": 1.0667, + "value": -8.85, + "curve": [ 1.121, -5.07, 1.219, -0.02 ] + }, + { + "time": 1.3333, + "value": 1.29, + "curve": [ 1.509, 3.3, 1.763, 2.75 ] + }, + { + "time": 1.8667, + "value": 2.78, + "curve": [ 1.974, 2.81, 2.108, 2.81 ] + }, + { + "time": 2.2, + "value": 2.78, + "curve": [ 2.315, 2.74, 2.374, 1.22 ] + }, + { + "time": 2.4667, + "value": 1.18, + "curve": [ 2.525, 1.18, 2.608, 10.79 ] + }, + { + "time": 2.6667, + "value": 10.79, + "curve": [ 2.725, 10.79, 2.893, 4.72 ] + }, + { + "time": 3.0333, + "value": 4.72, + "curve": [ 3.117, 4.72, 3.283, 7.93 ] + }, + { + "time": 3.3667, + "value": 7.93, + "curve": [ 3.492, 7.93, 3.775, 6.93 ] + }, + { + "time": 3.9, + "value": 6.93, + "curve": [ 3.981, 6.93, 4.094, 6.9 ] + }, + { + "time": 4.2, + "value": 8.44, + "curve": [ 4.267, 9.42, 4.401, 16.61 ] + }, + { + "time": 4.5, + "value": 16.33, + "curve": [ 4.582, 16.12, 4.709, 9.94 ] + }, + { + "time": 4.7333, + "value": 6.51, + "curve": [ 4.747, 4.57, 4.779, -1.76 ] + }, + { + "time": 4.8, + "value": -1.75, + "curve": [ 4.823, -1.73, 4.82, 4.47 ] + }, + { + "time": 4.8667, + "value": 6.04, + "curve": [ 4.899, 7.14, 4.913, 6.93 ] + }, + { "time": 4.9333, "value": 6.93 } + ] + }, + "hair2": { + "rotate": [ + { + "value": 10.61, + "curve": [ 0.075, 10.61, 0.05, 12.67 ] + }, + { + "time": 0.0667, + "value": 12.67, + "curve": [ 0.123, 12.67, 0.194, -16.51 ] + }, + { + "time": 0.2, + "value": -19.87, + "curve": [ 0.207, -23.48, 0.236, -31.68 ] + }, + { + "time": 0.3, + "value": -31.8, + "curve": [ 0.356, -31.9, 0.437, -25.61 ] + }, + { + "time": 0.4667, + "value": -19.29, + "curve": [ 0.485, -15.33, 0.529, 6.48 ] + }, + { + "time": 0.5667, + "value": 6.67, + "curve": [ 0.628, 6.97, 0.65, -46.39 ] + }, + { + "time": 0.7333, + "value": -46.3, + "curve": [ 0.843, -46.17, 0.941, -33.37 ] + }, + { + "time": 0.9667, + "value": -23.17, + "curve": [ 0.972, -20.98, 1.047, 15.21 ] + }, + { + "time": 1.1, + "value": 15.21, + "curve": [ 1.142, 15.21, 1.183, 10.73 ] + }, + { + "time": 1.2667, + "value": 10.61, + "curve": [ 1.45, 10.34, 1.817, 10.61 ] + }, + { + "time": 2, + "value": 10.61, + "curve": [ 2.075, 10.61, 2.225, 16.9 ] + }, + { + "time": 2.3, + "value": 16.9, + "curve": [ 2.327, 16.9, 2.347, 6.81 ] + }, + { + "time": 2.4, + "value": 6.83, + "curve": [ 2.492, 6.87, 2.602, 17.39 ] + }, + { + "time": 2.6667, + "value": 17.39, + "curve": [ 2.742, 17.39, 2.892, 10.67 ] + }, + { + "time": 2.9667, + "value": 10.64, + "curve": [ 3.187, 10.57, 3.344, 10.73 ] + }, + { + "time": 3.6, + "value": 11.4, + "curve": [ 3.766, 11.83, 3.874, 14.87 ] + }, + { + "time": 3.9333, + "value": 14.83, + "curve": [ 4.022, 14.76, 4.208, 9.49 ] + }, + { + "time": 4.3, + "value": 9.54, + "curve": [ 4.391, 9.58, 4.441, 14.82 ] + }, + { + "time": 4.5333, + "value": 14.84, + "curve": [ 4.642, 14.88, 4.692, 1.17 ] + }, + { + "time": 4.7667, + "value": 1.24, + "curve": [ 4.823, 1.3, 4.818, 18.35 ] + }, + { + "time": 4.8667, + "value": 18.38, + "curve": [ 4.905, 18.41, 4.901, 10.61 ] + }, + { "time": 4.9333, "value": 10.61 } + ] + }, + "torso2": { + "rotate": [ + { + "curve": [ 0.048, 0, 0.129, -12.73 ] + }, + { + "time": 0.1667, + "value": -15.95, + "curve": [ 0.221, -20.66, 0.254, -21.62 ] + }, + { + "time": 0.3, + "value": -21.59, + "curve": [ 0.458, -21.46, 0.46, -1.67 ] + }, + { + "time": 0.6333, + "value": -1.71, + "curve": [ 0.71, -1.73, 0.715, -4 ] + }, + { + "time": 0.7667, + "value": -3.97, + "curve": [ 0.866, -3.92, 0.84, 0.02 ] + }, + { "time": 1, "curve": "stepped" }, + { + "time": 2, + "curve": [ 2.275, 0, 2.867, -5.8 ] + }, + { + "time": 3.1, + "value": -6.44, + "curve": [ 3.327, -7.06, 3.71, -6.23 ] + }, + { + "time": 3.9333, + "value": -5.41, + "curve": [ 4.168, -4.53, 4.488, -2.83 ] + }, + { "time": 4.8 } + ] + }, + "torso3": { + "rotate": [ + { + "curve": [ 0.025, 0, 0.09, -3.66 ] + }, + { + "time": 0.1, + "value": -4.55, + "curve": [ 0.143, -8.4, 0.223, -17.07 ] + }, + { + "time": 0.2333, + "value": -18.31, + "curve": [ 0.282, -24.44, 0.35, -29 ] + }, + { + "time": 0.3667, + "value": -30.07, + "curve": [ 0.405, -32.58, 0.442, -33.03 ] + }, + { + "time": 0.4667, + "value": -32.99, + "curve": [ 0.491, -33.04, 0.505, -23.56 ] + }, + { + "time": 0.5333, + "value": -23.55, + "curve": [ 0.571, -23.67, 0.599, -27.21 ] + }, + { + "time": 0.6333, + "value": -27.21, + "curve": [ 0.669, -27.2, 0.742, -10.43 ] + }, + { + "time": 0.7667, + "value": -7.79, + "curve": [ 0.788, -5.53, 0.796, -4.42 ] + }, + { + "time": 0.8333, + "value": -2.9, + "curve": [ 0.875, -1.21, 0.933, 0 ] + }, + { "time": 0.9667, "curve": "stepped" }, + { + "time": 2.4333, + "curve": [ 2.517, 0, 2.683, 4.63 ] + }, + { + "time": 2.7667, + "value": 4.66, + "curve": [ 3.084, 4.76, 3.248, 4.37 ] + }, + { + "time": 3.4, + "value": 3.74, + "curve": [ 3.596, 2.92, 3.755, 2.18 ] + }, + { + "time": 3.8667, + "value": 1.72, + "curve": [ 4.136, 0.59, 4.471, 0 ] + }, + { "time": 4.8 } + ] + }, + "hair3": { + "rotate": [ + { + "curve": [ 0, 0, 0.041, 10.74 ] + }, + { + "time": 0.0667, + "value": 14.16, + "curve": [ 0.075, 15.22, 0.148, 18.04 ] + }, + { + "time": 0.2, + "value": 18.13, + "curve": [ 0.251, 18.23, 0.307, -4.75 ] + }, + { + "time": 0.3667, + "value": -5.06, + "curve": [ 0.412, -5.3, 0.47, -0.96 ] + }, + { + "time": 0.5, + "value": 2.21, + "curve": [ 0.512, 3.48, 0.595, 20.31 ] + }, + { + "time": 0.6333, + "value": 24.87, + "curve": [ 0.647, 26.53, 0.719, 29.33 ] + }, + { + "time": 0.8, + "value": 29.22, + "curve": [ 0.859, 29.14, 0.9, 28.48 ] + }, + { + "time": 0.9333, + "value": 26.11, + "curve": [ 0.981, 22.72, 0.998, 2.06 ] + }, + { "time": 1.1, "value": 2.21 } + ] + }, + "hair1": { + "rotate": [ + { + "curve": [ 0.047, -0.21, 0.048, 7.86 ] + }, + { + "time": 0.0667, + "value": 13.27, + "curve": [ 0.083, 18.05, 0.135, 24.44 ] + }, + { + "time": 0.2, + "value": 24.02, + "curve": [ 0.225, 24.02, 0.28, 6.32 ] + }, + { + "time": 0.3, + "value": 3.1, + "curve": [ 0.323, -0.58, 0.382, -7.12 ] + }, + { + "time": 0.4667, + "value": -7.45, + "curve": [ 0.512, -7.66, 0.538, 12.13 ] + }, + { + "time": 0.5667, + "value": 16.46, + "curve": [ 0.609, 22.72, 0.672, 27.4 ] + }, + { + "time": 0.7333, + "value": 27.55, + "curve": [ 0.827, 27.4, 0.933, 23.23 ] + }, + { + "time": 0.9667, + "value": 19.11, + "curve": [ 0.998, 15.27, 1.092, -2.53 ] + }, + { + "time": 1.1333, + "value": -2.53, + "curve": [ 1.158, -2.53, 1.208, 0 ] + }, + { "time": 1.2333, "curve": "stepped" }, + { + "time": 2, + "curve": [ 2.075, 0, 2.248, 0.35 ] + }, + { + "time": 2.3333, + "value": 0.78, + "curve": [ 2.585, 2.06, 2.805, 3.46 ] + }, + { + "time": 3.2, + "value": 3.5, + "curve": [ 3.593, 3.54, 3.979, 2.36 ] + }, + { + "time": 4.1667, + "value": 1.55, + "curve": [ 4.391, 0.59, 4.447, 0.04 ] + }, + { + "time": 4.6, + "value": 0.04, + "curve": [ 4.642, 0.04, 4.742, 0 ] + }, + { "time": 4.9333 } + ] + }, + "head-control": { + "translate": [ + { + "curve": [ 0.025, 0, 0.09, 1.43, 0.025, 0, 0.075, -34.76 ] + }, + { + "time": 0.1, + "x": 1.59, + "y": -34.76, + "curve": [ 0.214, 3.33, 0.375, 5.34, 0.192, -34.76, 0.441, -21.17 ] + }, + { + "time": 0.4667, + "x": 5.34, + "y": -12.57, + "curve": [ 0.492, 5.34, 0.55, 5.24, 0.482, -7.36, 0.504, 4.03 ] + }, + { + "time": 0.5667, + "x": 5.11, + "y": 4.01, + "curve": [ 0.658, 4.45, 0.679, 3.19, 0.649, 3.98, 0.642, -16.84 ] + }, + { + "time": 0.7, + "x": 2.8, + "y": -16.74, + "curve": [ 0.787, 1.15, 0.881, -1.29, 0.772, -16.62, 0.82, 8.95 ] + }, + { + "time": 0.9, + "x": -1.72, + "y": 8.91, + "curve": [ 0.961, -3.06, 1.025, -3.58, 0.975, 8.87, 0.951, -1.37 ] + }, + { + "time": 1.1, + "x": -3.58, + "y": -1.45, + "curve": [ 1.292, -3.58, 2.002, -2.4, 1.292, -1.56, 1.975, -1.45 ] + }, + { + "time": 2.1667, + "x": -1.39, + "y": -1.45, + "curve": [ 2.25, -0.88, 2.503, 1.38, 2.283, -1.45, 2.603, -12.44 ] + }, + { + "time": 2.6667, + "x": 2.13, + "y": -14.45, + "curve": [ 2.766, 2.59, 2.999, 2.81, 2.835, -19.73, 3.003, -25.2 ] + }, + { + "time": 3.1333, + "x": 2.91, + "y": -26.08, + "curve": [ 3.392, 3.1, 4.199, 4.05, 3.483, -28.44, 4.129, -27.23 ] + }, + { + "time": 4.3667, + "x": 4.81, + "y": -19.59, + "curve": [ 4.429, 5.1, 4.594, 8.54, 4.538, -14.08, 4.583, -7.88 ] + }, + { + "time": 4.6667, + "x": 8.65, + "y": -4.56, + "curve": [ 4.794, 8.86, 4.806, 5.93, 4.691, -3.59, 4.8, -1.61 ] + }, + { "time": 4.9333, "x": 5.8, "y": -1.99 } + ] + } + }, + "ik": { + "front-foot-ik": [ + { "mix": 0 } + ], + "front-leg-ik": [ + { "mix": 0, "bendPositive": false } + ], + "rear-foot-ik": [ + { "mix": 0.005 } + ], + "rear-leg-ik": [ + { "mix": 0.005, "bendPositive": false } + ] + } + }, + "hoverboard": { + "slots": { + "exhaust1": { + "attachment": [ + { "name": "hoverglow-small" } + ] + }, + "exhaust2": { + "attachment": [ + { "name": "hoverglow-small" } + ] + }, + "exhaust3": { + "attachment": [ + { "name": "hoverglow-small" } + ] + }, + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + }, + "hoverboard-board": { + "attachment": [ + { "name": "hoverboard-board" } + ] + }, + "hoverboard-thruster-front": { + "attachment": [ + { "name": "hoverboard-thruster" } + ] + }, + "hoverboard-thruster-rear": { + "attachment": [ + { "name": "hoverboard-thruster" } + ] + }, + "hoverglow-front": { + "attachment": [ + { "name": "hoverglow-small" } + ] + }, + "hoverglow-rear": { + "attachment": [ + { "name": "hoverglow-small" } + ] + }, + "side-glow1": { + "attachment": [ + { "name": "hoverglow-small" }, + { "time": 0.9667 } + ] + }, + "side-glow2": { + "attachment": [ + { "time": 0.0667, "name": "hoverglow-small" }, + { "time": 1 } + ] + }, + "side-glow3": { + "attachment": [ + { "name": "hoverglow-small" }, + { "time": 0.9667 } + ] + } + }, + "bones": { + "hoverboard-controller": { + "translate": [ + { + "x": 319.55, + "y": -1.59, + "curve": [ 0.064, 319.55, 0.2, 347.85, 0.058, -1.2, 0.2, 23.11 ] + }, + { + "time": 0.2667, + "x": 347.66, + "y": 39.62, + "curve": [ 0.35, 347.41, 0.476, 341.47, 0.323, 53.58, 0.44, 85.82 ] + }, + { + "time": 0.5333, + "x": 338.47, + "y": 85.72, + "curve": [ 0.603, 334.83, 0.913, 319.65, 0.621, 85.62, 0.88, -1.53 ] + }, + { "time": 1, "x": 319.55, "y": -1.59 } + ] + }, + "hip": { + "translate": [ + { + "x": -53.49, + "y": 32.14, + "curve": [ 0.061, -53.77, 0.093, -51.81, 0.044, 16.34, 0.063, 9.67 ] + }, + { + "time": 0.1333, + "x": -49.31, + "y": 7.01, + "curve": [ 0.3, -35.27, 0.461, -20.06, 0.314, 9.52, 0.408, 121.09 ] + }, + { + "time": 0.5667, + "x": -20.06, + "y": 122.72, + "curve": [ 0.716, -20.09, 0.912, -53.29, 0.753, 121.8, 0.946, 51.85 ] + }, + { "time": 1, "x": -53.49, "y": 32.14 } + ] + }, + "exhaust1": { + "scale": [ + { + "x": 1.593, + "y": 0.964, + "curve": [ 0.033, 1.593, 0.1, 1, 0.033, 0.964, 0.1, 0.713 ] + }, + { + "time": 0.1333, + "y": 0.713, + "curve": [ 0.15, 1, 0.183, 1.774, 0.15, 0.713, 0.183, 0.883 ] + }, + { + "time": 0.2, + "x": 1.774, + "y": 0.883, + "curve": [ 0.242, 1.774, 0.325, 1.181, 0.242, 0.883, 0.325, 0.649 ] + }, + { + "time": 0.3667, + "x": 1.181, + "y": 0.649, + "curve": [ 0.408, 1.181, 0.492, 1.893, 0.408, 0.649, 0.492, 0.819 ] + }, + { + "time": 0.5333, + "x": 1.893, + "y": 0.819, + "curve": [ 0.558, 1.893, 0.608, 1.18, 0.558, 0.819, 0.608, 0.686 ] + }, + { + "time": 0.6333, + "x": 1.18, + "y": 0.686, + "curve": [ 0.658, 1.18, 0.708, 1.903, 0.658, 0.686, 0.708, 0.855 ] + }, + { + "time": 0.7333, + "x": 1.903, + "y": 0.855, + "curve": [ 0.767, 1.903, 0.833, 1.311, 0.767, 0.855, 0.833, 0.622 ] + }, + { + "time": 0.8667, + "x": 1.311, + "y": 0.622, + "curve": [ 0.9, 1.311, 0.967, 1.593, 0.9, 0.622, 0.967, 0.964 ] + }, + { "time": 1, "x": 1.593, "y": 0.964 } + ] + }, + "exhaust2": { + "scale": [ + { + "x": 1.88, + "y": 0.832, + "curve": [ 0.025, 1.88, 0.075, 1.311, 0.025, 0.832, 0.075, 0.686 ] + }, + { + "time": 0.1, + "x": 1.311, + "y": 0.686, + "curve": [ 0.133, 1.311, 0.2, 2.01, 0.133, 0.686, 0.208, 0.736 ] + }, + { + "time": 0.2333, + "x": 2.01, + "y": 0.769, + "curve": [ 0.267, 2.01, 0.333, 1, 0.282, 0.831, 0.333, 0.91 ] + }, + { + "time": 0.3667, + "y": 0.91, + "curve": [ 0.4, 1, 0.467, 1.699, 0.4, 0.91, 0.474, 0.891 ] + }, + { + "time": 0.5, + "x": 1.699, + "y": 0.86, + "curve": [ 0.517, 1.699, 0.55, 1.181, 0.54, 0.813, 0.55, 0.713 ] + }, + { + "time": 0.5667, + "x": 1.181, + "y": 0.713, + "curve": [ 0.617, 1.181, 0.717, 1.881, 0.617, 0.713, 0.717, 0.796 ] + }, + { + "time": 0.7667, + "x": 1.881, + "y": 0.796, + "curve": [ 0.8, 1.881, 0.867, 1.3, 0.8, 0.796, 0.867, 0.649 ] + }, + { + "time": 0.9, + "x": 1.3, + "y": 0.649, + "curve": [ 0.925, 1.3, 0.975, 1.88, 0.925, 0.649, 0.975, 0.832 ] + }, + { "time": 1, "x": 1.88, "y": 0.832 } + ] + }, + "hoverboard-thruster-front": { + "rotate": [ + { + "curve": [ 0.125, 0, 0.375, 24.06 ] + }, + { + "time": 0.5, + "value": 24.06, + "curve": [ 0.625, 24.06, 0.875, 0 ] + }, + { "time": 1 } + ] + }, + "hoverglow-front": { + "scale": [ + { + "x": 0.849, + "y": 1.764, + "curve": [ 0.017, 0.849, 0.05, 0.835, 0.017, 1.764, 0.05, 2.033 ] + }, + { + "time": 0.0667, + "x": 0.835, + "y": 2.033, + "curve": [ 0.092, 0.835, 0.142, 0.752, 0.092, 2.033, 0.142, 1.584 ] + }, + { + "time": 0.1667, + "x": 0.752, + "y": 1.584, + "curve": [ 0.183, 0.752, 0.217, 0.809, 0.183, 1.584, 0.217, 1.71 ] + }, + { + "time": 0.2333, + "x": 0.809, + "y": 1.71, + "curve": [ 0.25, 0.809, 0.283, 0.717, 0.25, 1.71, 0.283, 1.45 ] + }, + { + "time": 0.3, + "x": 0.717, + "y": 1.45, + "curve": [ 0.317, 0.717, 0.35, 0.777, 0.317, 1.45, 0.35, 1.698 ] + }, + { + "time": 0.3667, + "x": 0.777, + "y": 1.698, + "curve": [ 0.4, 0.781, 0.45, 0.685, 0.375, 1.698, 0.45, 1.173 ] + }, + { + "time": 0.4667, + "x": 0.685, + "y": 1.173, + "curve": [ 0.492, 0.685, 0.542, 0.825, 0.492, 1.173, 0.542, 1.572 ] + }, + { + "time": 0.5667, + "x": 0.825, + "y": 1.572, + "curve": [ 0.611, 0.816, 0.63, 0.727, 0.611, 1.577, 0.606, 1.255 ] + }, + { + "time": 0.6667, + "x": 0.725, + "y": 1.241, + "curve": [ 0.692, 0.725, 0.742, 0.895, 0.692, 1.241, 0.749, 1.799 ] + }, + { + "time": 0.7667, + "x": 0.895, + "y": 1.857, + "curve": [ 0.783, 0.895, 0.796, 0.892, 0.796, 1.955, 0.817, 1.962 ] + }, + { + "time": 0.8333, + "x": 0.845, + "y": 1.962, + "curve": [ 0.845, 0.831, 0.883, 0.802, 0.85, 1.962, 0.872, 1.704 ] + }, + { + "time": 0.9, + "x": 0.802, + "y": 1.491, + "curve": [ 0.917, 0.802, 0.95, 0.845, 0.907, 1.441, 0.936, 1.508 ] + }, + { + "time": 0.9667, + "x": 0.845, + "y": 1.627, + "curve": [ 0.975, 0.845, 0.992, 0.849, 0.973, 1.652, 0.992, 1.764 ] + }, + { "time": 1, "x": 0.849, "y": 1.764 } + ] + }, + "hoverboard-thruster-rear": { + "rotate": [ + { + "curve": [ 0.125, 0, 0.375, 24.06 ] + }, + { + "time": 0.5, + "value": 24.06, + "curve": [ 0.625, 24.06, 0.875, 0 ] + }, + { "time": 1 } + ] + }, + "hoverglow-rear": { + "scale": [ + { + "x": 0.845, + "y": 1.31, + "curve": [ 0.017, 0.845, 0.117, 0.899, 0.017, 1.31, 0.117, 2.033 ] + }, + { + "time": 0.1333, + "x": 0.899, + "y": 2.033, + "curve": [ 0.15, 0.899, 0.183, 0.752, 0.15, 2.033, 0.183, 1.574 ] + }, + { + "time": 0.2, + "x": 0.752, + "y": 1.574, + "curve": [ 0.225, 0.752, 0.275, 0.809, 0.225, 1.574, 0.275, 1.71 ] + }, + { + "time": 0.3, + "x": 0.809, + "y": 1.71, + "curve": [ 0.317, 0.809, 0.35, 0.717, 0.317, 1.71, 0.35, 1.397 ] + }, + { + "time": 0.3667, + "x": 0.717, + "y": 1.397, + "curve": [ 0.383, 0.717, 0.417, 0.777, 0.383, 1.397, 0.417, 1.45 ] + }, + { + "time": 0.4333, + "x": 0.777, + "y": 1.45, + "curve": [ 0.45, 0.777, 0.496, 0.689, 0.45, 1.45, 0.481, 1.168 ] + }, + { + "time": 0.5333, + "x": 0.685, + "y": 1.173, + "curve": [ 0.565, 0.682, 0.617, 0.758, 0.575, 1.177, 0.617, 1.297 ] + }, + { + "time": 0.6333, + "x": 0.758, + "y": 1.297, + "curve": [ 0.658, 0.758, 0.708, 0.725, 0.658, 1.297, 0.708, 1.241 ] + }, + { + "time": 0.7333, + "x": 0.725, + "y": 1.241, + "curve": [ 0.772, 0.732, 0.796, 0.893, 0.782, 1.238, 0.778, 1.854 ] + }, + { + "time": 0.8333, + "x": 0.895, + "y": 1.857, + "curve": [ 0.878, 0.9, 0.992, 0.845, 0.88, 1.86, 0.992, 1.31 ] + }, + { "time": 1, "x": 0.845, "y": 1.31 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -85.92, + "curve": [ 0.08, -85.59, 0.284, -62.7 ] + }, + { + "time": 0.3667, + "value": -55.14, + "curve": [ 0.438, -48.65, 0.551, -43.21 ] + }, + { + "time": 0.6333, + "value": -43.21, + "curve": [ 0.716, -43.22, 0.908, -85.92 ] + }, + { "time": 1, "value": -85.92 } + ], + "translate": [ + { + "x": -0.59, + "y": -2.94, + "curve": [ 0.1, -1.21, 0.275, -1.74, 0.092, -2.94, 0.275, -6.39 ] + }, + { + "time": 0.3667, + "x": -1.74, + "y": -6.39, + "curve": [ 0.433, -1.74, 0.567, 0.72, 0.433, -6.39, 0.587, -4.48 ] + }, + { + "time": 0.6333, + "x": 0.72, + "y": -4.21, + "curve": [ 0.725, 0.72, 0.908, -0.08, 0.743, -3.57, 0.908, -2.94 ] + }, + { "time": 1, "x": -0.59, "y": -2.94 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": 7.61, + "curve": [ 0.143, 7.62, 0.247, -23.17 ] + }, + { + "time": 0.2667, + "value": -26.56, + "curve": [ 0.281, -29.08, 0.351, -37.36 ] + }, + { + "time": 0.4333, + "value": -37.2, + "curve": [ 0.513, -37.05, 0.562, -29.88 ] + }, + { + "time": 0.6, + "value": -25.18, + "curve": [ 0.621, -22.58, 0.694, -3.98 ] + }, + { + "time": 0.8, + "value": 3.63, + "curve": [ 0.861, 8.03, 0.946, 7.57 ] + }, + { "time": 1, "value": 7.61 } + ], + "translate": [ + { + "curve": [ 0.117, 0, 0.35, 0.52, 0.117, 0, 0.35, -3.27 ] + }, + { + "time": 0.4667, + "x": 0.52, + "y": -3.27, + "curve": [ 0.6, 0.52, 0.867, 0, 0.6, -3.27, 0.867, 0 ] + }, + { "time": 1 } + ], + "shear": [ + { + "y": 19.83, + "curve": [ 0.117, 0, 0.35, 15.28, 0.117, 19.83, 0.35, 28.31 ] + }, + { + "time": 0.4667, + "x": 15.28, + "y": 28.31, + "curve": [ 0.6, 15.28, 0.867, 0, 0.6, 28.31, 0.867, 19.83 ] + }, + { "time": 1, "y": 19.83 } + ] + }, + "board-ik": { + "translate": [ + { + "x": 393.62, + "curve": [ 0.083, 393.62, 0.25, 393.48, 0.083, 0, 0.25, 117.69 ] + }, + { + "time": 0.3333, + "x": 393.48, + "y": 117.69, + "curve": [ 0.375, 393.48, 0.458, 393.62, 0.375, 117.69, 0.458, 83.82 ] + }, + { "time": 0.5, "x": 393.62, "y": 83.82 }, + { "time": 0.6667, "x": 393.62, "y": 30.15 }, + { "time": 1, "x": 393.62 } + ] + }, + "front-thigh": { + "translate": [ + { "x": -7.49, "y": 8.51 } + ] + }, + "front-leg-target": { + "translate": [ + { + "time": 0.3667, + "curve": [ 0.428, 10.83, 0.567, 12.78, 0.414, 7.29, 0.567, 8.79 ] + }, + { + "time": 0.6, + "x": 12.78, + "y": 8.79, + "curve": [ 0.692, 12.78, 0.772, 11.27, 0.692, 8.79, 0.766, 8.62 ] + }, + { "time": 0.8667 } + ] + }, + "rear-leg-target": { + "translate": [ + { + "time": 0.4667, + "curve": [ 0.492, 0, 0.534, 4.47, 0.492, 0, 0.542, 1.63 ] + }, + { + "time": 0.5667, + "x": 4.53, + "y": 1.77, + "curve": [ 0.622, 4.64, 0.717, 3.31, 0.615, 2.06, 0.71, 2.1 ] + }, + { "time": 0.8 } + ] + }, + "exhaust3": { + "scale": [ + { + "x": 1.882, + "y": 0.81, + "curve": [ 0.017, 1.882, 0.167, 1.3, 0.017, 0.81, 0.167, 0.649 ] + }, + { + "time": 0.2, + "x": 1.3, + "y": 0.649, + "curve": [ 0.225, 1.3, 0.275, 2.051, 0.225, 0.649, 0.275, 0.984 ] + }, + { + "time": 0.3, + "x": 2.051, + "y": 0.984, + "curve": [ 0.325, 2.051, 0.375, 1.311, 0.325, 0.984, 0.384, 0.715 ] + }, + { + "time": 0.4, + "x": 1.311, + "y": 0.686, + "curve": [ 0.433, 1.311, 0.5, 1.86, 0.426, 0.638, 0.5, 0.537 ] + }, + { + "time": 0.5333, + "x": 1.86, + "y": 0.537, + "curve": [ 0.567, 1.86, 0.633, 1.187, 0.567, 0.537, 0.604, 0.854 ] + }, + { + "time": 0.6667, + "x": 1.187, + "y": 0.854, + "curve": [ 0.7, 1.187, 0.767, 1.549, 0.707, 0.854, 0.774, 0.775 ] + }, + { + "time": 0.8, + "x": 1.549, + "y": 0.746, + "curve": [ 0.817, 1.549, 0.85, 1.181, 0.815, 0.729, 0.85, 0.713 ] + }, + { + "time": 0.8667, + "x": 1.181, + "y": 0.713, + "curve": [ 0.9, 1.181, 0.967, 1.882, 0.9, 0.713, 0.967, 0.81 ] + }, + { "time": 1, "x": 1.882, "y": 0.81 } + ] + }, + "side-glow1": { + "rotate": [ + { "value": 51.12, "curve": "stepped" }, + { "time": 0.0667, "value": 43.82, "curve": "stepped" }, + { "time": 0.1, "value": 40.95, "curve": "stepped" }, + { "time": 0.1667, "value": 27.78, "curve": "stepped" }, + { "time": 0.2, "value": 10.24, "curve": "stepped" }, + { "time": 0.2667, "curve": "stepped" }, + { "time": 0.8, "value": -25.81 } + ], + "translate": [ + { "x": 338.28, "y": 40.22, "curve": "stepped" }, + { "time": 0.0667, "x": 331.2, "y": 30.39, "curve": "stepped" }, + { "time": 0.1, "x": 318.63, "y": 20.59, "curve": "stepped" }, + { "time": 0.1667, "x": 302.45, "y": 9.64, "curve": "stepped" }, + { "time": 0.2, "x": 276.87, "y": 1.13, "curve": "stepped" }, + { "time": 0.2667, "x": 248.16, "curve": "stepped" }, + { "time": 0.3, "x": 221.36, "curve": "stepped" }, + { "time": 0.3667, "x": 195.69, "curve": "stepped" }, + { "time": 0.4, "x": 171.08, "curve": "stepped" }, + { "time": 0.4667, "x": 144.84, "curve": "stepped" }, + { "time": 0.5, "x": 121.22, "curve": "stepped" }, + { "time": 0.5667, "x": 91.98, "curve": "stepped" }, + { "time": 0.6, "x": 62.63, "curve": "stepped" }, + { "time": 0.6667, "x": 30.78, "curve": "stepped" }, + { "time": 0.7, "curve": "stepped" }, + { "time": 0.7667, "x": -28.45, "curve": "stepped" }, + { "time": 0.8, "x": -67.49, "y": 16.82, "curve": "stepped" }, + { "time": 0.8667, "x": -83.07, "y": 24.36, "curve": "stepped" }, + { "time": 0.9, "x": -93.81, "y": 29.55 } + ], + "scale": [ + { "x": 0.535, "curve": "stepped" }, + { "time": 0.0667, "x": 0.594, "curve": "stepped" }, + { "time": 0.1, "x": 0.844, "curve": "stepped" }, + { "time": 0.1667, "curve": "stepped" }, + { "time": 0.8, "x": 0.534, "curve": "stepped" }, + { "time": 0.8667, "x": 0.428, "y": 0.801, "curve": "stepped" }, + { "time": 0.9, "x": 0.349, "y": 0.654 } + ] + }, + "side-glow2": { + "rotate": [ + { "time": 0.0667, "value": 51.12, "curve": "stepped" }, + { "time": 0.1, "value": 43.82, "curve": "stepped" }, + { "time": 0.1667, "value": 40.95, "curve": "stepped" }, + { "time": 0.2, "value": 27.78, "curve": "stepped" }, + { "time": 0.2667, "value": 10.24, "curve": "stepped" }, + { "time": 0.3, "curve": "stepped" }, + { "time": 0.8667, "value": -25.81 } + ], + "translate": [ + { "time": 0.0667, "x": 338.28, "y": 40.22, "curve": "stepped" }, + { "time": 0.1, "x": 331.2, "y": 30.39, "curve": "stepped" }, + { "time": 0.1667, "x": 318.63, "y": 20.59, "curve": "stepped" }, + { "time": 0.2, "x": 302.45, "y": 9.64, "curve": "stepped" }, + { "time": 0.2667, "x": 276.87, "y": 1.13, "curve": "stepped" }, + { "time": 0.3, "x": 248.16, "curve": "stepped" }, + { "time": 0.3667, "x": 221.36, "curve": "stepped" }, + { "time": 0.4, "x": 195.69, "curve": "stepped" }, + { "time": 0.4667, "x": 171.08, "curve": "stepped" }, + { "time": 0.5, "x": 144.84, "curve": "stepped" }, + { "time": 0.5667, "x": 121.22, "curve": "stepped" }, + { "time": 0.6, "x": 91.98, "curve": "stepped" }, + { "time": 0.6667, "x": 62.63, "curve": "stepped" }, + { "time": 0.7, "x": 30.78, "curve": "stepped" }, + { "time": 0.7667, "curve": "stepped" }, + { "time": 0.8, "x": -28.45, "curve": "stepped" }, + { "time": 0.8667, "x": -67.49, "y": 16.82, "curve": "stepped" }, + { "time": 0.9, "x": -83.07, "y": 24.36, "curve": "stepped" }, + { "time": 0.9667, "x": -93.81, "y": 29.55 } + ], + "scale": [ + { "time": 0.0667, "x": 0.535, "curve": "stepped" }, + { "time": 0.1, "x": 0.594, "curve": "stepped" }, + { "time": 0.1667, "x": 0.844, "curve": "stepped" }, + { "time": 0.2, "curve": "stepped" }, + { "time": 0.8667, "x": 0.534, "curve": "stepped" }, + { "time": 0.9, "x": 0.428, "y": 0.801, "curve": "stepped" }, + { "time": 0.9667, "x": 0.349, "y": 0.654 } + ] + }, + "torso": { + "rotate": [ + { + "value": -34.73, + "curve": [ 0.034, -36.31, 0.162, -39.33 ] + }, + { + "time": 0.2667, + "value": -39.37, + "curve": [ 0.384, -39.37, 0.491, -29.52 ] + }, + { + "time": 0.5, + "value": -28.86, + "curve": [ 0.525, -26.95, 0.571, -21.01 ] + }, + { + "time": 0.6333, + "value": -21.01, + "curve": [ 0.725, -21.01, 0.969, -33.35 ] + }, + { "time": 1, "value": -34.73 } + ] + }, + "neck": { + "rotate": [ + { + "value": 10.2, + "curve": [ 0.07, 12.09, 0.189, 16.03 ] + }, + { + "time": 0.2667, + "value": 16.14, + "curve": [ 0.333, 16.14, 0.449, 8.03 ] + }, + { + "time": 0.5, + "value": 5.83, + "curve": [ 0.542, 4.02, 0.6, 2.68 ] + }, + { + "time": 0.6333, + "value": 2.68, + "curve": [ 0.725, 2.68, 0.943, 8.57 ] + }, + { "time": 1, "value": 10.2 } + ] + }, + "head": { + "rotate": [ + { + "value": 10.2, + "curve": [ 0.044, 11.52, 0.2, 16.12 ] + }, + { + "time": 0.2667, + "value": 16.14, + "curve": [ 0.375, 16.17, 0.492, 2.65 ] + }, + { + "time": 0.6333, + "value": 2.68, + "curve": [ 0.725, 2.7, 0.963, 9.26 ] + }, + { "time": 1, "value": 10.2 } + ], + "translate": [ + { + "curve": [ 0.03, -0.24, 0.2, -4.22, 0.051, -1.06, 0.2, -3.62 ] + }, + { + "time": 0.2667, + "x": -4.22, + "y": -3.62, + "curve": [ 0.358, -4.22, 0.542, 0.84, 0.358, -3.62, 0.542, 6.01 ] + }, + { + "time": 0.6333, + "x": 0.84, + "y": 6.01, + "curve": [ 0.725, 0.84, 0.939, 0.32, 0.725, 6.01, 0.945, 1.14 ] + }, + { "time": 1 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": -11.18, + "curve": [ 0.064, -14.82, 0.25, -20.01 ] + }, + { + "time": 0.3333, + "value": -20.01, + "curve": [ 0.429, -20.12, 0.58, 5.12 ] + }, + { + "time": 0.6, + "value": 8.67, + "curve": [ 0.617, 11.72, 0.687, 20.52 ] + }, + { + "time": 0.7667, + "value": 20.55, + "curve": [ 0.848, 20.7, 0.963, -9.43 ] + }, + { "time": 1, "value": -11.18 } + ] + }, + "hair3": { + "rotate": [ + { + "value": 9.61, + "curve": [ 0.014, 8.51, 0.075, 2.63 ] + }, + { + "time": 0.1, + "value": 2.63, + "curve": [ 0.15, 2.63, 0.25, 13.52 ] + }, + { + "time": 0.3, + "value": 13.52, + "curve": [ 0.35, 13.52, 0.45, 11.28 ] + }, + { + "time": 0.5, + "value": 11.28, + "curve": [ 0.575, 11.28, 0.725, 18.13 ] + }, + { + "time": 0.8, + "value": 18.13, + "curve": [ 0.85, 18.13, 0.978, 11.07 ] + }, + { "time": 1, "value": 9.61 } + ] + }, + "hair4": { + "rotate": [ + { + "value": -17.7, + "curve": [ 0.008, -17.7, 0.025, -23.73 ] + }, + { + "time": 0.0333, + "value": -23.73, + "curve": [ 0.067, -23.73, 0.154, -4.4 ] + }, + { + "time": 0.1667, + "value": -1.92, + "curve": [ 0.197, 4.09, 0.236, 12.91 ] + }, + { + "time": 0.2667, + "value": 17.56, + "curve": [ 0.301, 22.68, 0.342, 27.97 ] + }, + { + "time": 0.3667, + "value": 27.97, + "curve": [ 0.4, 27.97, 0.467, -1.45 ] + }, + { + "time": 0.5, + "value": -1.45, + "curve": [ 0.517, -1.45, 0.55, 3.16 ] + }, + { + "time": 0.5667, + "value": 3.16, + "curve": [ 0.583, 3.16, 0.617, -8.9 ] + }, + { + "time": 0.6333, + "value": -8.9, + "curve": [ 0.642, -8.9, 0.658, -5.4 ] + }, + { + "time": 0.6667, + "value": -5.4, + "curve": [ 0.683, -5.4, 0.717, -15.32 ] + }, + { + "time": 0.7333, + "value": -15.32, + "curve": [ 0.75, -15.32, 0.783, -9.19 ] + }, + { + "time": 0.8, + "value": -9.19, + "curve": [ 0.817, -9.19, 0.85, -23.6 ] + }, + { + "time": 0.8667, + "value": -23.6, + "curve": [ 0.883, -23.6, 0.917, -17.38 ] + }, + { + "time": 0.9333, + "value": -17.38, + "curve": [ 0.942, -17.38, 0.958, -20.46 ] + }, + { + "time": 0.9667, + "value": -20.46, + "curve": [ 0.975, -20.46, 0.992, -17.7 ] + }, + { "time": 1, "value": -17.7 } + ] + }, + "hair1": { + "rotate": [ + { + "value": 9.61, + "curve": [ 0.06, 9.04, 0.25, 8.9 ] + }, + { + "time": 0.3333, + "value": 8.9, + "curve": [ 0.392, 8.9, 0.508, 14.58 ] + }, + { + "time": 0.5667, + "value": 14.58, + "curve": [ 0.675, 14.58, 0.956, 10.28 ] + }, + { "time": 1, "value": 9.61 } + ] + }, + "hair2": { + "rotate": [ + { + "value": -3.82, + "curve": [ 0.017, -3.82, 0.064, -9.16 ] + }, + { + "time": 0.1333, + "value": -9.09, + "curve": [ 0.178, -9.04, 0.234, 1.29 ] + }, + { + "time": 0.2667, + "value": 5.98, + "curve": [ 0.276, 7.27, 0.336, 17.1 ] + }, + { + "time": 0.3667, + "value": 17.1, + "curve": [ 0.413, 17.1, 0.467, 1.59 ] + }, + { + "time": 0.5, + "value": 1.59, + "curve": [ 0.533, 1.59, 0.567, 13.63 ] + }, + { + "time": 0.6, + "value": 13.63, + "curve": [ 0.617, 13.63, 0.683, 0.78 ] + }, + { + "time": 0.7, + "value": 0.78, + "curve": [ 0.717, 0.78, 0.75, 12.01 ] + }, + { + "time": 0.7667, + "value": 11.9, + "curve": [ 0.792, 11.73, 0.817, -0.85 ] + }, + { + "time": 0.8333, + "value": -0.85, + "curve": [ 0.85, -0.85, 0.88, 1.99 ] + }, + { + "time": 0.9, + "value": 1.82, + "curve": [ 0.916, 1.68, 0.95, -6.9 ] + }, + { + "time": 0.9667, + "value": -6.9, + "curve": [ 0.975, -6.9, 0.992, -3.82 ] + }, + { "time": 1, "value": -3.82 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 31.65, + "curve": [ 0.108, 31.65, 0.325, 13.01 ] + }, + { + "time": 0.4333, + "value": 13.01, + "curve": [ 0.71, 13.01, 0.917, 31.65 ] + }, + { "time": 1, "value": 31.65 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": 31, + "curve": [ 0.108, 31, 0.325, 12.76 ] + }, + { + "time": 0.4333, + "value": 12.79, + "curve": [ 0.587, 12.82, 0.917, 31 ] + }, + { "time": 1, "value": 31 } + ] + }, + "gun": { + "rotate": [ + { + "value": 1.95, + "curve": [ 0.083, 1.95, 0.245, 36.73 ] + }, + { + "time": 0.3333, + "value": 36.71, + "curve": [ 0.439, 36.69, 0.589, 10.68 ] + }, + { + "time": 0.6333, + "value": 8.75, + "curve": [ 0.701, 5.81, 0.917, 1.95 ] + }, + { "time": 1, "value": 1.95 } + ] + }, + "torso2": { + "rotate": [ + { + "curve": [ 0.033, 0, 0.1, 2.35 ] + }, + { + "time": 0.1333, + "value": 2.35, + "curve": [ 0.225, 2.35, 0.408, -2.4 ] + }, + { + "time": 0.5, + "value": -2.4, + "curve": [ 0.567, -2.4, 0.7, 1.44 ] + }, + { + "time": 0.7667, + "value": 1.44, + "curve": [ 0.825, 1.44, 0.942, 0 ] + }, + { "time": 1 } + ] + }, + "torso3": { + "rotate": [ + { + "curve": [ 0.063, 0.77, 0.106, 1.42 ] + }, + { + "time": 0.1667, + "value": 1.42, + "curve": [ 0.259, 1.42, 0.344, -1.25 ] + }, + { + "time": 0.4667, + "value": -1.26, + "curve": [ 0.656, -1.26, 0.917, -0.78 ] + }, + { "time": 1 } + ] + }, + "head-control": { + "translate": [ + { + "x": 0.37, + "y": -11.17, + "curve": [ 0.133, 0.37, 0.335, -10.23, 0.133, -11.17, 0.335, 3.15 ] + }, + { + "time": 0.5333, + "x": -10.23, + "y": 3.15, + "curve": [ 0.71, -10.23, 0.883, 0.37, 0.71, 3.15, 0.883, -11.17 ] + }, + { "time": 1, "x": 0.37, "y": -11.17 } + ] + }, + "front-shoulder": { + "translate": [ + { + "x": 1.46, + "y": 10.15, + "curve": [ 0.103, 1.46, 0.249, 1.36, 0.103, 10.15, 0.249, -4.39 ] + }, + { + "time": 0.4, + "x": 1.36, + "y": -4.39, + "curve": [ 0.621, 1.36, 0.85, 1.46, 0.621, -4.39, 0.85, 10.15 ] + }, + { "time": 1, "x": 1.46, "y": 10.15 } + ] + }, + "back-shoulder": { + "translate": [ + { + "x": 1.4, + "y": 0.44, + "curve": [ 0.088, 1.4, 0.208, -2.47, 0.088, 0.44, 0.208, 8.61 ] + }, + { + "time": 0.3333, + "x": -2.47, + "y": 8.61, + "curve": [ 0.572, -2.47, 0.833, 1.4, 0.572, 8.61, 0.833, 0.44 ] + }, + { "time": 1, "x": 1.4, "y": 0.44 } + ] + } + }, + "transform": { + "front-foot-board-transform": [ + { "mixRotate": 0.997 } + ], + "rear-foot-board-transform": [ + {} + ], + "toes-board": [ + { "mixX": 0, "mixScaleX": 0, "mixShearY": 0 } + ] + }, + "attachments": { + "default": { + "front-foot": { + "front-foot": { + "deform": [ + { + "offset": 26, + "vertices": [ -0.02832, -5.37024, -0.02832, -5.37024, 3.8188, -3.7757, -0.02832, -5.37024, -3.82159, 3.77847 ] + } + ] + } + }, + "front-shin": { + "front-shin": { + "deform": [ + { + "offset": 14, + "vertices": [ 0.5298, -1.12677, -0.85507, -4.20587, -11.35158, -10.19225, -10.79865, -8.43765, -6.06447, -6.89757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.54892, -3.06021, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.80437, -7.01817 ] + }, + { + "time": 0.3667, + "offset": 14, + "vertices": [ 0.5298, -1.12677, -11.66571, -9.07211, -25.65866, -17.53735, -25.53217, -16.50978, -11.78232, -11.26097, 0, 0, 0.60487, -1.63589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.60487, -1.63589, 0, 0, -2.64522, -7.35739, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0.60487, -1.63589, 0.60487, -1.63589, 0.60487, -1.63589, 0.60487, -1.63589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.60487, -1.63589, 0, 0, -10.06873, -12.0999 ] + }, + { + "time": 0.5333, + "offset": 14, + "vertices": [ 0.5298, -1.12677, -0.85507, -4.20587, -7.00775, -8.24771, -6.45482, -6.49312, -6.06447, -6.89757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.54892, -3.06021, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.80437, -7.01817 ] + }, + { + "time": 1, + "offset": 14, + "vertices": [ 0.5298, -1.12677, -0.85507, -4.20587, -11.35158, -10.19225, -10.79865, -8.43765, -6.06447, -6.89757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.54892, -3.06021, 1.48463, -2.29663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.80437, -7.01817 ] + } + ] + } + }, + "hoverboard-board": { + "hoverboard-board": { + "deform": [ + { + "curve": [ 0.067, 0, 0.2, 1 ] + }, + { + "time": 0.2667, + "offset": 1, + "vertices": [ 2.45856, 0, 0, 0, 0, 0, 0, 0, 0, 3.55673, -3.0E-4, 3.55673, -3.0E-4, 0, 0, 0, 0, 0, 0, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, -7.6E-4, -9.84158, 0, 0, 0, 0, 0, 0, 0, 0, -4.90558, 0.11214, -9.40706, 6.2E-4, -6.34871, 4.3E-4, -6.34925, -6.57018, -6.34925, -6.57018, -6.34871, 4.3E-4, -2.3308, 1.7E-4, -2.33133, -6.57045, -2.33133, -6.57045, -2.3308, 1.7E-4, 0, 0, 1.2E-4, 2.45856, 1.2E-4, 2.45856, 1.2E-4, 2.45856, 1.2E-4, 2.45856, 3.3297, 4.44005, 3.3297, 4.44005, 3.3297, 4.44005, 1.2E-4, 2.45856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.46227, 1.7E-4, -2.46227, 1.7E-4, -2.52316, 1.1313, -2.52316, 1.1313, -2.52316, 1.1313, 1.2E-4, 2.45856, 1.2E-4, 2.45856, -9.40694, 2.45918, 1.88063, 0.44197, -2.9E-4, -3.54808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.52316, 1.1313, -2.52316, 1.1313, -2.52316, 1.1313, -2.46227, 1.7E-4, -2.46227, 1.7E-4, -2.46227, 1.7E-4, 0, 0, 0, 0, 1.2E-4, 2.45856 ], + "curve": [ 0.45, 0, 0.817, 1 ] + }, + { "time": 1 } + ] + } + }, + "rear-foot": { + "rear-foot": { + "deform": [ + { + "offset": 28, + "vertices": [ -1.93078, 1.34782, -0.31417, 2.33363, 3.05122, 0.33946, 2.31472, -2.01678, 2.17583, -2.05795, -0.04277, -2.99459, 1.15429, 0.26328, 0.97501, -0.67169 ] + } + ] + } + } + } + } + }, + "idle": { + "slots": { + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + } + }, + "bones": { + "front-foot-target": { + "translate": [ + { "x": -69.06 } + ] + }, + "hip": { + "rotate": [ + { + "curve": [ 0.073, 0.35, 0.303, 1.27 ] + }, + { + "time": 0.4, + "value": 1.28, + "curve": [ 0.615, 1.3, 0.847, -1.41 ] + }, + { + "time": 1.2, + "value": -1.38, + "curve": [ 1.344, -1.37, 1.602, -0.28 ] + }, + { "time": 1.6667 } + ], + "translate": [ + { + "x": -11.97, + "y": -23.15, + "curve": [ 0.059, -12.96, 0.258, -15.19, 0.142, -23.15, 0.341, -24.89 ] + }, + { + "time": 0.4667, + "x": -15.14, + "y": -26.74, + "curve": [ 0.62, -15.1, 0.788, -13.28, 0.597, -28.66, 0.75, -30.01 ] + }, + { + "time": 0.9, + "x": -12.02, + "y": -30.01, + "curve": [ 0.978, -11.13, 1.175, -9.05, 1.036, -29.94, 1.234, -28.08 ] + }, + { + "time": 1.3333, + "x": -9.06, + "y": -26.64, + "curve": [ 1.501, -9.06, 1.614, -10.95, 1.454, -24.89, 1.609, -23.15 ] + }, + { "time": 1.6667, "x": -11.97, "y": -23.15 } + ] + }, + "rear-foot-target": { + "translate": [ + { "x": 48.87 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -60.87, + "curve": [ 0.154, -60.85, 0.452, -68.65 ] + }, + { + "time": 0.8333, + "value": -68.65, + "curve": [ 1.221, -68.65, 1.542, -60.87 ] + }, + { "time": 1.6667, "value": -60.87 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 42.46, + "curve": [ 0.029, 42.97, 0.134, 45.28 ] + }, + { + "time": 0.3333, + "value": 45.27, + "curve": [ 0.578, 45.26, 0.798, 40.07 ] + }, + { + "time": 0.8333, + "value": 39.74, + "curve": [ 0.878, 39.32, 1.019, 38.23 ] + }, + { + "time": 1.2, + "value": 38.22, + "curve": [ 1.377, 38.22, 1.619, 41.68 ] + }, + { "time": 1.6667, "value": 42.46 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 39.2, + "curve": [ 0.185, 39.22, 0.5, 29.37 ] + }, + { + "time": 0.6667, + "value": 29.37, + "curve": [ 0.917, 29.37, 1.417, 39.2 ] + }, + { "time": 1.6667, "value": 39.2 } + ] + }, + "head": { + "rotate": [ + { + "value": -6.75, + "curve": [ 0.176, -7.88, 0.349, -8.95 ] + }, + { + "time": 0.4667, + "value": -8.95, + "curve": [ 0.55, -8.95, 0.697, -6.77 ] + }, + { + "time": 0.8333, + "value": -5.44, + "curve": [ 0.88, -4.98, 1.05, -4.12 ] + }, + { + "time": 1.1333, + "value": -4.12, + "curve": [ 1.266, -4.12, 1.469, -5.48 ] + }, + { "time": 1.6667, "value": -6.75 } + ] + }, + "front-fist": { + "rotate": [ + { + "curve": [ 0.086, 0, 0.233, 2.48 ] + }, + { + "time": 0.3333, + "value": 4.13, + "curve": [ 0.429, 5.7, 0.711, 10.06 ] + }, + { + "time": 0.8333, + "value": 10.06, + "curve": [ 0.926, 10.06, 1.092, 4.21 ] + }, + { + "time": 1.2, + "value": 2.78, + "curve": [ 1.349, 0.8, 1.551, 0 ] + }, + { "time": 1.6667 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "curve": [ 0.063, 0.54, 0.367, 3.39 ] + }, + { + "time": 0.5333, + "value": 3.39, + "curve": [ 0.696, 3.39, 0.939, -1.63 ] + }, + { + "time": 1.2, + "value": -1.61, + "curve": [ 1.42, -1.59, 1.574, -0.67 ] + }, + { "time": 1.6667 } + ] + }, + "gun": { + "rotate": [ + { + "curve": [ 0.099, 0.27, 0.367, 1.23 ] + }, + { + "time": 0.5333, + "value": 1.23, + "curve": [ 0.665, 1.23, 0.937, -0.56 ] + }, + { + "time": 1.1333, + "value": -0.55, + "curve": [ 1.316, -0.55, 1.582, -0.21 ] + }, + { "time": 1.6667 } + ] + }, + "torso": { + "rotate": [ + { + "value": -22.88, + "curve": [ 0.099, -23.45, 0.363, -24.74 ] + }, + { + "time": 0.5333, + "value": -24.74, + "curve": [ 0.706, -24.74, 0.961, -20.97 ] + }, + { + "time": 1.1333, + "value": -20.97, + "curve": [ 1.355, -20.97, 1.567, -22.28 ] + }, + { "time": 1.6667, "value": -22.88 } + ] + }, + "neck": { + "rotate": [ + { + "value": 3.78, + "curve": [ 0.167, 3.78, 0.5, 5.45 ] + }, + { + "time": 0.6667, + "value": 5.45, + "curve": [ 0.917, 5.45, 1.417, 3.78 ] + }, + { "time": 1.6667, "value": 3.78 } + ] + }, + "torso2": { + "rotate": [ + { + "curve": [ 0.067, 0.33, 0.341, 2.54 ] + }, + { + "time": 0.5333, + "value": 2.54, + "curve": [ 0.734, 2.55, 0.982, -0.94 ] + }, + { + "time": 1.1333, + "value": -0.93, + "curve": [ 1.365, -0.91, 1.549, -0.56 ] + }, + { "time": 1.6667 } + ] + }, + "torso3": { + "rotate": [ + { + "value": -2.15, + "curve": [ 0.052, -1.9, 0.384, -0.15 ] + }, + { + "time": 0.5333, + "value": -0.14, + "curve": [ 0.762, -0.13, 0.895, -3.1 ] + }, + { + "time": 1.1333, + "value": -3.1, + "curve": [ 1.348, -3.1, 1.592, -2.46 ] + }, + { "time": 1.6667, "value": -2.15 } + ] + }, + "hair1": { + "rotate": [ + { + "curve": [ 0.067, 0, 0.213, 2.86 ] + }, + { + "time": 0.2667, + "value": 3.65, + "curve": [ 0.358, 4.99, 0.535, 7.92 ] + }, + { + "time": 0.6667, + "value": 7.92, + "curve": [ 0.809, 7.92, 1.067, 5.49 ] + }, + { + "time": 1.1333, + "value": 4.7, + "curve": [ 1.245, 3.34, 1.525, 0 ] + }, + { "time": 1.6667 } + ] + }, + "hair2": { + "rotate": [ + { + "curve": [ 0.067, 0, 0.225, -7.97 ] + }, + { + "time": 0.2667, + "value": -9.75, + "curve": [ 0.316, -11.84, 0.519, -16.66 ] + }, + { + "time": 0.6667, + "value": -16.66, + "curve": [ 0.817, -16.66, 1.029, -11.43 ] + }, + { + "time": 1.1333, + "value": -9.14, + "curve": [ 1.25, -6.56, 1.525, 0 ] + }, + { "time": 1.6667 } + ] + }, + "hair3": { + "rotate": [ + { + "curve": [ 0.1, 0, 0.3, 1.32 ] + }, + { + "time": 0.4, + "value": 1.32, + "curve": [ 0.55, 1.32, 0.866, 0.93 ] + }, + { + "time": 1, + "value": 0.73, + "curve": [ 1.189, 0.46, 1.5, 0 ] + }, + { "time": 1.6667 } + ] + }, + "hair4": { + "rotate": [ + { + "curve": [ 0.118, -0.44, 0.3, -8.52 ] + }, + { + "time": 0.4, + "value": -8.52, + "curve": [ 0.55, -8.52, 0.85, 1.96 ] + }, + { + "time": 1, + "value": 1.96, + "curve": [ 1.167, 1.96, 1.577, 0.38 ] + }, + { "time": 1.6667 } + ] + }, + "head-control": { + "translate": [ + { + "curve": [ 0.098, 1.46, 0.3, 4.49, 0.17, 0.13, 0.316, -3.28 ] + }, + { + "time": 0.4, + "x": 4.55, + "y": -5.95, + "curve": [ 0.53, 4.64, 0.776, 2.59, 0.492, -8.89, 0.668, -14.21 ] + }, + { + "time": 0.8667, + "x": 1.42, + "y": -14.26, + "curve": [ 0.966, 0.15, 1.109, -2.91, 0.994, -14.26, 1.144, -10.58 ] + }, + { + "time": 1.2333, + "x": -3.02, + "y": -8.26, + "curve": [ 1.342, -3.02, 1.568, -1.48, 1.317, -6.1, 1.558, 0 ] + }, + { "time": 1.6667 } + ] + }, + "front-shoulder": { + "translate": [ + { + "curve": [ 0.21, 0, 0.525, -1.72, 0.21, 0, 0.525, 4.08 ] + }, + { + "time": 0.8333, + "x": -1.72, + "y": 4.08, + "curve": [ 1.15, -1.72, 1.46, 0, 1.15, 4.08, 1.46, 0 ] + }, + { "time": 1.6667 } + ] + } + } + }, + "idle-turn": { + "slots": { + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + } + }, + "bones": { + "front-upper-arm": { + "rotate": [ + { + "value": -302.77, + "curve": [ 0, -406.9, 0.125, -420.87 ] + }, + { "time": 0.2667, "value": -420.87 } + ], + "translate": [ + { + "x": 2.24, + "y": -4.98, + "curve": [ 0.067, 2.24, 0.111, 0, 0.067, -4.98, 0.111, 0 ] + }, + { "time": 0.2667 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 248.56, + "curve": [ 0, 371.28, 0.062, 399.2 ] + }, + { "time": 0.1333, "value": 399.2 } + ], + "translate": [ + { + "x": -2.84, + "y": 37.28, + "curve": [ 0.033, -2.84, 0.069, 0, 0.033, 37.28, 0.069, 0 ] + }, + { "time": 0.1333 } + ] + }, + "gun": { + "rotate": [ + { + "value": -3.95, + "curve": [ 0, -10.4, 0.019, -20.43 ] + }, + { + "time": 0.0333, + "value": -20.45, + "curve": [ 0.044, -20.47, 0.125, 0 ] + }, + { "time": 0.2 } + ] + }, + "neck": { + "rotate": [ + { + "value": 17.2, + "curve": [ 0, 6.27, 0.125, 3.78 ] + }, + { "time": 0.2667, "value": 3.78 } + ] + }, + "hip": { + "translate": [ + { + "x": -2.69, + "y": -6.79, + "curve": [ 0.067, -2.69, 0.2, -11.97, 0.067, -6.79, 0.2, -23.15 ] + }, + { "time": 0.2667, "x": -11.97, "y": -23.15 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -15.54, + "curve": [ 0, -3.08, 0.034, 18.44 ] + }, + { + "time": 0.0667, + "value": 19.02, + "curve": [ 0.108, 19.75, 0.169, 0 ] + }, + { "time": 0.2667 } + ], + "scale": [ + { + "x": 0.94, + "curve": [ 0, 0.962, 0.024, 1.237, 0, 1, 0.026, 0.947 ] + }, + { + "time": 0.0667, + "x": 1.236, + "y": 0.947, + "curve": [ 0.117, 1.235, 0.189, 1, 0.117, 0.947, 0.189, 1 ] + }, + { "time": 0.2667 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": 11.75, + "curve": [ 0, -7.97, 0.017, -33.4 ] + }, + { + "time": 0.0333, + "value": -33.39, + "curve": [ 0.049, -33.37, 0.131, 0 ] + }, + { "time": 0.2 } + ] + }, + "torso": { + "rotate": [ + { + "value": -18.25, + "curve": [ 0, -10.59, 0.125, -22.88 ] + }, + { "time": 0.2667, "value": -22.88 } + ], + "scale": [ + { + "y": 1.03, + "curve": [ 0.067, 1, 0.132, 1, 0.067, 1.03, 0.132, 1 ] + }, + { "time": 0.2667 } + ] + }, + "head": { + "rotate": [ + { + "value": 5.12, + "curve": [ 0, -6.34, 0.125, -6.75 ] + }, + { "time": 0.2667, "value": -6.75 } + ], + "scale": [ + { + "y": 1.03, + "curve": [ 0.067, 1, 0.107, 1, 0.067, 1.03, 0.107, 1 ] + }, + { "time": 0.2667 } + ] + }, + "rear-foot-target": { + "translate": [ + { + "x": -58.39, + "y": 30.48, + "curve": [ 0, -7.15, 0.047, 16.62, 0, 12.71, 0.039, 0.22 ] + }, + { + "time": 0.1, + "x": 34.14, + "y": -0.19, + "curve": [ 0.136, 45.79, 0.163, 48.87, 0.133, -0.41, 0.163, 0 ] + }, + { "time": 0.2, "x": 48.87 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 6.69, + "curve": [ 0, 19.76, 0.039, 56.53 ] + }, + { + "time": 0.0667, + "value": 56.63, + "curve": [ 0.114, 56.79, 0.189, 42.46 ] + }, + { "time": 0.2667, "value": 42.46 } + ] + }, + "front-foot-target": { + "rotate": [ + { + "value": -1.85, + "curve": [ 0.014, -8.91, 0.047, -28.4 ] + }, + { + "time": 0.1, + "value": -28.89, + "curve": [ 0.144, -29.29, 0.262, -21.77 ] + }, + { "time": 0.2667 } + ], + "translate": [ + { + "x": 9.97, + "y": 0.82, + "curve": [ 0, -54.41, 0.078, -69.06, 0, 0.15, 0.078, 0 ] + }, + { "time": 0.1667, "x": -69.06 } + ] + }, + "hair3": { + "rotate": [ + { + "value": -9.01, + "curve": [ 0.044, -9.01, 0.072, 7.41 ] + }, + { + "time": 0.1333, + "value": 10.08, + "curve": [ 0.166, 11.47, 0.208, 0 ] + }, + { "time": 0.2667 } + ] + }, + "hair4": { + "rotate": [ + { + "value": -16.49, + "curve": [ 0.044, -16.49, 0.101, -5.98 ] + }, + { + "time": 0.1333, + "value": -2.95, + "curve": [ 0.162, -0.34, 0.208, 0 ] + }, + { "time": 0.2667 } + ] + }, + "hair1": { + "rotate": [ + { + "value": -3.85, + "curve": [ 0.044, -3.85, 0.072, 6.91 ] + }, + { + "time": 0.1333, + "value": 8.05, + "curve": [ 0.166, 8.65, 0.208, 0 ] + }, + { "time": 0.2667 } + ] + }, + "hair2": { + "rotate": [ + { + "value": 1.25, + "curve": [ 0.044, 1.25, 0.072, 8.97 ] + }, + { + "time": 0.1333, + "value": 8.6, + "curve": [ 0.166, 8.4, 0.208, 0 ] + }, + { "time": 0.2667 } + ] + }, + "front-thigh": { + "translate": [ + { + "x": 12.21, + "y": 1.89, + "curve": [ 0.033, 12.21, 0.1, 0, 0.033, 1.89, 0.1, 0 ] + }, + { "time": 0.1333 } + ] + }, + "rear-thigh": { + "translate": [ + { + "x": -16.11, + "y": -1.38, + "curve": [ 0.033, -16.11, 0.1, 0, 0.033, -1.38, 0.1, 0 ] + }, + { "time": 0.1333 } + ] + }, + "torso3": { + "rotate": [ + { "time": 0.2667, "value": -2.15 } + ] + }, + "head-control": { + "translate": [ + { + "x": -13.72, + "y": -34.7, + "curve": [ 0.067, -13.72, 0.2, 0, 0.067, -34.7, 0.2, 0 ] + }, + { "time": 0.2667 } + ] + }, + "front-shoulder": { + "translate": [ + { + "x": 1.13, + "y": -14.31, + "curve": [ 0.067, 1.13, 0.2, 0, 0.067, -14.31, 0.2, 0 ] + }, + { "time": 0.2667 } + ] + } + } + }, + "jump": { + "slots": { + "front-fist": { + "attachment": [ + { "name": "front-fist-open" }, + { "time": 0.1, "name": "front-fist-closed" }, + { "time": 0.8333, "name": "front-fist-open" } + ] + } + }, + "bones": { + "front-thigh": { + "rotate": [ + { + "value": 55.08, + "curve": [ 0.007, 46.66, 0.043, 26.3 ] + }, + { + "time": 0.0667, + "value": 22.84, + "curve": [ 0.1, 17.99, 0.165, 15.78 ] + }, + { + "time": 0.2333, + "value": 15.71, + "curve": [ 0.309, 15.63, 0.408, 46.67 ] + }, + { + "time": 0.5, + "value": 63.6, + "curve": [ 0.56, 74.72, 0.762, 91.48 ] + }, + { + "time": 0.9667, + "value": 91.81, + "curve": [ 1.068, 92.01, 1.096, 22.05 ] + }, + { + "time": 1.1667, + "value": 22.25, + "curve": [ 1.18, 22.29, 1.176, 56.17 ] + }, + { + "time": 1.2, + "value": 56.16, + "curve": [ 1.246, 56.15, 1.263, 54.94 ] + }, + { "time": 1.3333, "value": 55.08 } + ], + "translate": [ + { "x": -5.13, "y": 11.55 } + ] + }, + "torso": { + "rotate": [ + { + "value": -45.57, + "curve": [ 0.022, -44.61, 0.03, -39.06 ] + }, + { + "time": 0.0667, + "value": -35.29, + "curve": [ 0.12, -29.77, 0.28, -19.95 ] + }, + { + "time": 0.4333, + "value": -19.95, + "curve": [ 0.673, -19.95, 0.871, -22.38 ] + }, + { + "time": 0.9667, + "value": -27.08, + "curve": [ 1.094, -33.33, 1.176, -44.93 ] + }, + { "time": 1.3333, "value": -45.57 } + ], + "translate": [ + { "x": -3.79, "y": -0.77 } + ] + }, + "rear-thigh": { + "rotate": [ + { + "value": 12.81, + "curve": [ 0.067, 12.81, 0.242, 67.88 ] + }, + { + "time": 0.2667, + "value": 74.11, + "curve": [ 0.314, 86.02, 0.454, 92.23 ] + }, + { + "time": 0.5667, + "value": 92.24, + "curve": [ 0.753, 92.26, 0.966, 67.94 ] + }, + { + "time": 1, + "value": 61.32, + "curve": [ 1.039, 53.75, 1.218, 12.68 ] + }, + { "time": 1.3333, "value": 12.81 } + ] + }, + "rear-shin": { + "rotate": [ + { + "value": -115.64, + "curve": [ 0.067, -117.17, 0.125, -117.15 ] + }, + { + "time": 0.1667, + "value": -117.15, + "curve": [ 0.225, -117.15, 0.332, -108.76 ] + }, + { + "time": 0.4, + "value": -107.15, + "curve": [ 0.48, -105.26, 0.685, -103.49 ] + }, + { + "time": 0.7667, + "value": -101.97, + "curve": [ 0.826, -100.87, 0.919, -92.3 ] + }, + { + "time": 1, + "value": -92.28, + "curve": [ 1.113, -92.26, 1.297, -114.22 ] + }, + { "time": 1.3333, "value": -115.64 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -40.21, + "curve": [ 0.054, -35.46, 0.15, -31.12 ] + }, + { + "time": 0.2, + "value": -31.12, + "curve": [ 0.308, -31.12, 0.547, -80.12 ] + }, + { + "time": 0.6333, + "value": -96.56, + "curve": [ 0.697, -108.56, 0.797, -112.54 ] + }, + { + "time": 0.8667, + "value": -112.6, + "curve": [ 1.137, -112.84, 1.274, -49.19 ] + }, + { "time": 1.3333, "value": -40.21 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 20.54, + "curve": [ 0.054, 32.23, 0.192, 55.84 ] + }, + { + "time": 0.2333, + "value": 62.58, + "curve": [ 0.29, 71.87, 0.375, 79.28 ] + }, + { + "time": 0.4333, + "value": 79.18, + "curve": [ 0.555, 78.98, 0.684, 27.54 ] + }, + { + "time": 0.7333, + "value": 13.28, + "curve": [ 0.786, -1.85, 0.874, -24.76 ] + }, + { + "time": 1, + "value": -25.45, + "curve": [ 1.165, -26.36, 1.303, 9.1 ] + }, + { "time": 1.3333, "value": 20.54 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -36.16, + "curve": [ 0.114, -39.59, 0.3, -45.61 ] + }, + { + "time": 0.4, + "value": -45.61, + "curve": [ 0.442, -45.61, 0.537, -21.54 ] + }, + { + "time": 0.5667, + "value": -15.4, + "curve": [ 0.592, -10.23, 0.692, 11.89 ] + }, + { + "time": 0.7333, + "value": 11.73, + "curve": [ 0.783, 11.54, 0.831, 1.8 ] + }, + { + "time": 0.8667, + "value": -5.78, + "curve": [ 0.897, -12.22, 0.901, -14.22 ] + }, + { + "time": 0.9333, + "value": -14.51, + "curve": [ 0.974, -14.89, 0.976, 10.38 ] + }, + { + "time": 1, + "value": 10.55, + "curve": [ 1.027, 10.74, 1.023, -8.44 ] + }, + { + "time": 1.0333, + "value": -8.42, + "curve": [ 1.059, -8.36, 1.074, 10.12 ] + }, + { + "time": 1.1, + "value": 10.22, + "curve": [ 1.168, 10.48, 1.27, -36.07 ] + }, + { "time": 1.3333, "value": -36.16 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 40.5, + "curve": [ 0.048, 36.1, 0.168, 20.45 ] + }, + { + "time": 0.3, + "value": 20.45, + "curve": [ 0.476, 20.45, 0.571, 33.76 ] + }, + { + "time": 0.6, + "value": 38.67, + "curve": [ 0.642, 45.8, 0.681, 57.44 ] + }, + { + "time": 0.7333, + "value": 62.91, + "curve": [ 0.829, 72.8, 0.996, 77.61 ] + }, + { + "time": 1.0333, + "value": 80.37, + "curve": [ 1.082, 83.94, 1.148, 90.6 ] + }, + { + "time": 1.2, + "value": 90.6, + "curve": [ 1.248, 90.46, 1.317, 53.07 ] + }, + { "time": 1.3333, "value": 49.06 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": 28.28, + "curve": [ 0.022, 25.12, 0.187, -0.89 ] + }, + { + "time": 0.2, + "value": -2.52, + "curve": [ 0.257, -9.92, 0.372, -17.38 ] + }, + { + "time": 0.4333, + "value": -17.41, + "curve": [ 0.54, -17.47, 0.659, -16.91 ] + }, + { + "time": 0.7667, + "value": -12.1, + "curve": [ 0.907, -5.79, 1.025, 14.58 ] + }, + { + "time": 1.1, + "value": 20.58, + "curve": [ 1.191, 27.85, 1.283, 29.67 ] + }, + { "time": 1.3333, "value": 29.67 } + ] + }, + "neck": { + "rotate": [ + { + "value": 11.88, + "curve": [ 0.104, 11.82, 0.179, 11.15 ] + }, + { + "time": 0.2, + "value": 10.08, + "curve": [ 0.255, 7.29, 0.405, -8.15 ] + }, + { + "time": 0.4333, + "value": -9.35, + "curve": [ 0.508, -12.48, 0.595, -13.14 ] + }, + { + "time": 0.6667, + "value": -12.61, + "curve": [ 0.714, -12.26, 0.815, -5.57 ] + }, + { + "time": 0.8333, + "value": -4.08, + "curve": [ 0.883, -0.07, 1.045, 12.77 ] + }, + { + "time": 1.1, + "value": 15.06, + "curve": [ 1.208, 19.6, 1.279, 20.64 ] + }, + { "time": 1.3333, "value": 20.73 } + ] + }, + "head": { + "rotate": [ + { + "value": 13.14, + "curve": [ 0.008, 12.19, 0.197, -23.53 ] + }, + { + "time": 0.3333, + "value": -23.95, + "curve": [ 0.509, -23.95, 0.667, -2.66 ] + }, + { + "time": 0.7333, + "value": -2.66, + "curve": [ 0.792, -2.66, 0.908, -13.32 ] + }, + { + "time": 0.9667, + "value": -13.32, + "curve": [ 1.158, -13.11, 1.241, -1.58 ] + }, + { "time": 1.3333, "value": -1.58 } + ], + "scale": [ + { + "curve": [ 0.041, 1, 0.052, 0.962, 0.041, 1, 0.052, 1.137 ] + }, + { + "time": 0.1, + "x": 0.954, + "y": 1.137, + "curve": [ 0.202, 0.962, 0.318, 1, 0.202, 1.137, 0.252, 1.002 ] + }, + { "time": 0.4667 }, + { + "time": 1.0667, + "x": 1.002, + "curve": [ 1.092, 1.002, 1.126, 1.143, 1.092, 1, 1.128, 0.975 ] + }, + { + "time": 1.1667, + "x": 1.144, + "y": 0.973, + "curve": [ 1.204, 1.145, 1.233, 0.959, 1.206, 0.972, 1.227, 1.062 ] + }, + { + "time": 1.2667, + "x": 0.958, + "y": 1.063, + "curve": [ 1.284, 0.958, 1.292, 1.001, 1.288, 1.063, 1.288, 1.001 ] + }, + { "time": 1.3333 } + ] + }, + "hip": { + "translate": [ + { + "y": -45.46, + "curve": [ 0.042, -0.09, 0.15, 15.22, 0.031, 44.98, 0.123, 289.73 ] + }, + { + "time": 0.2, + "x": 15.22, + "y": 415.85, + "curve": [ 0.332, 15.22, 0.539, -34.52, 0.271, 532.93, 0.483, 720.5 ] + }, + { + "time": 0.7667, + "x": -34.52, + "y": 721.6, + "curve": [ 0.888, -34.52, 1.057, -21.95, 1.049, 721.17, 1.098, 379.84 ] + }, + { + "time": 1.1333, + "x": -15.67, + "y": 266.77, + "curve": [ 1.144, -14.77, 1.188, -10.53, 1.15, 213.72, 1.172, -61.32 ] + }, + { + "time": 1.2333, + "x": -6.53, + "y": -61.34, + "curve": [ 1.272, -3.22, 1.311, 0.05, 1.291, -61.36, 1.296, -44.8 ] + }, + { "time": 1.3333, "y": -45.46 } + ] + }, + "front-shin": { + "rotate": [ + { + "value": -74.19, + "curve": [ 0, -51.14, 0.042, -12.54 ] + }, + { + "time": 0.1667, + "value": -12.28, + "curve": [ 0.285, -12.32, 0.37, -74.44 ] + }, + { + "time": 0.4333, + "value": -92.92, + "curve": [ 0.498, -111.86, 0.617, -140.28 ] + }, + { + "time": 0.9, + "value": -140.84, + "curve": [ 1.004, -141.04, 1.09, -47.87 ] + }, + { + "time": 1.1, + "value": -37.44, + "curve": [ 1.108, -29.83, 1.14, -21.18 ] + }, + { + "time": 1.1667, + "value": -21.08, + "curve": [ 1.18, -21.03, 1.191, -50.65 ] + }, + { + "time": 1.2, + "value": -53.17, + "curve": [ 1.22, -58.53, 1.271, -73.38 ] + }, + { "time": 1.3333, "value": -74.19 } + ] + }, + "front-foot": { + "rotate": [ + { + "value": 7.35, + "curve": [ 0, 4.8, 0.05, -26.64 ] + }, + { + "time": 0.0667, + "value": -26.64, + "curve": [ 0.192, -26.64, 0.442, -11.77 ] + }, + { + "time": 0.5667, + "value": -11.77, + "curve": [ 0.692, -11.77, 0.942, -19.36 ] + }, + { + "time": 1.0667, + "value": -19.36, + "curve": [ 1.133, -19.36, 1.32, 3.82 ] + }, + { "time": 1.3333, "value": 7.35 } + ] + }, + "rear-foot": { + "rotate": [ + { "value": -7.14 } + ] + }, + "gun": { + "rotate": [ + { + "value": 12.36, + "curve": [ 0.022, 16.28, 0.15, 30.81 ] + }, + { + "time": 0.2, + "value": 30.81, + "curve": [ 0.258, 30.81, 0.375, 13.26 ] + }, + { + "time": 0.4333, + "value": 13.26, + "curve": [ 0.508, 13.26, 0.658, 15.05 ] + }, + { + "time": 0.7333, + "value": 14.98, + "curve": [ 0.789, 14.94, 0.828, 13.62 ] + }, + { + "time": 0.8667, + "value": 12.72, + "curve": [ 0.887, 12.25, 0.984, 9.83 ] + }, + { + "time": 1.0333, + "value": 8.6, + "curve": [ 1.045, 8.31, 1.083, 7.55 ] + }, + { + "time": 1.1333, + "value": 7.13, + "curve": [ 1.175, 6.78, 1.283, 6.18 ] + }, + { "time": 1.3333, "value": 6.18 } + ] + }, + "front-leg-target": { + "translate": [ + { "x": -13.95, "y": -30.34 } + ] + }, + "rear-leg-target": { + "rotate": [ + { "value": -38.43 } + ], + "translate": [ + { "x": 85, "y": -33.59 } + ] + }, + "front-foot-target": { + "rotate": [ + { "value": -62.54 } + ], + "translate": [ + { "x": 16.34, "y": 0.18 } + ] + }, + "rear-foot-target": { + "rotate": [ + { "value": 18.55 } + ], + "translate": [ + { "x": -176.39, "y": 134.12 } + ] + }, + "back-foot-tip": { + "rotate": [ + { + "value": -143.73, + "curve": [ 0.083, -144.24, 0.167, -74.26 ] + }, + { + "time": 0.2667, + "value": -52.76, + "curve": [ 0.342, -36.57, 0.513, -36.57 ] + }, + { + "time": 0.6333, + "value": -30.97, + "curve": [ 0.724, -26.78, 0.848, -17.06 ] + }, + { + "time": 0.9667, + "value": -16.74, + "curve": [ 1.167, -16.2, 1.272, -144.17 ] + }, + { "time": 1.3333, "value": -143.73 } + ] + }, + "front-foot-tip": { + "rotate": [ + { + "value": -1.57, + "curve": [ 0, -24.71, 0.162, -60.88 ] + }, + { + "time": 0.2667, + "value": -60.83, + "curve": [ 0.342, -60.8, 0.582, -43.5 ] + }, + { + "time": 0.7, + "value": -39.45, + "curve": [ 0.773, -36.94, 0.832, -36.78 ] + }, + { + "time": 0.9667, + "value": -36.6, + "curve": [ 1.054, -36.49, 1.092, -37.37 ] + }, + { + "time": 1.1667, + "value": -33.26, + "curve": [ 1.237, -29.37, 1.147, -1.41 ] + }, + { "time": 1.2, "value": -1.57 } + ] + }, + "hair3": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0, 13.59, 0.117, 18.21 ] + }, + { + "time": 0.1333, + "value": 18.21, + "curve": [ 0.167, 18.21, 0.26, 12.95 ] + }, + { + "time": 0.3, + "value": 11.56, + "curve": [ 0.382, 8.7, 0.55, 9.43 ] + }, + { + "time": 0.6667, + "value": 9.32, + "curve": [ 0.843, 9.15, 0.918, -7.34 ] + }, + { "time": 1.3333, "value": -6.81 } + ], + "translate": [ + { + "time": 0.6667, + "curve": [ 0.781, 0, 0.972, 16.03, 0.781, 0, 0.972, 0.92 ] + }, + { + "time": 1.1333, + "x": 16.03, + "y": 0.92, + "curve": [ 1.211, 16.03, 1.281, 0, 1.211, 0.92, 1.281, 0 ] + }, + { "time": 1.3333 } + ] + }, + "hair4": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0.001, -3.88, 0.063, 16.18 ] + }, + { + "time": 0.1667, + "value": 16.14, + "curve": [ 0.242, 16.1, 0.249, 16.07 ] + }, + { + "time": 0.3333, + "value": 13.46, + "curve": [ 0.442, 10.09, 0.573, -2.2 ] + }, + { + "time": 0.6, + "value": -6.04, + "curve": [ 0.614, -8.05, 0.717, -33.44 ] + }, + { + "time": 0.7667, + "value": -33.44, + "curve": [ 0.809, -33.44, 0.835, -31.32 ] + }, + { + "time": 0.8667, + "value": -27.36, + "curve": [ 0.874, -26.47, 0.903, -14.28 ] + }, + { + "time": 0.9333, + "value": -14.47, + "curve": [ 0.956, -14.62, 0.944, -25.91 ] + }, + { + "time": 1, + "value": -25.96, + "curve": [ 1.062, -26.02, 1.051, -1.87 ] + }, + { + "time": 1.0667, + "value": -1.87, + "curve": [ 1.096, -1.87, 1.096, -16.09 ] + }, + { + "time": 1.1333, + "value": -16.08, + "curve": [ 1.169, -16.08, 1.153, -3.38 ] + }, + { + "time": 1.2, + "value": -3.38, + "curve": [ 1.234, -3.38, 1.271, -6.07 ] + }, + { "time": 1.3333, "value": -6.07 } + ] + }, + "hair2": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0, -3.17, 0.042, 16.33 ] + }, + { + "time": 0.0667, + "value": 16.33, + "curve": [ 0.21, 15.74, 0.208, -12.06 ] + }, + { + "time": 0.3333, + "value": -12.21, + "curve": [ 0.417, -12.3, 0.552, -3.98 ] + }, + { + "time": 0.6667, + "value": 1.52, + "curve": [ 0.726, 4.35, 0.817, 4.99 ] + }, + { + "time": 0.8667, + "value": 4.99, + "curve": [ 0.901, 4.99, 0.912, -29.05 ] + }, + { + "time": 0.9667, + "value": -27.45, + "curve": [ 0.987, -26.83, 1.018, -5.42 ] + }, + { + "time": 1.0667, + "value": -5.46, + "curve": [ 1.107, -5.22, 1.095, -33.51 ] + }, + { + "time": 1.1333, + "value": -33.28, + "curve": [ 1.162, -33.57, 1.192, 8.04 ] + }, + { + "time": 1.2667, + "value": 7.86, + "curve": [ 1.302, 7.77, 1.313, 2.7 ] + }, + { "time": 1.3333, "value": 2.7 } + ] + }, + "hair1": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0.001, -3.12, 0.074, 14.66 ] + }, + { + "time": 0.1333, + "value": 14.66, + "curve": [ 0.188, 14.8, 0.293, 9.56 ] + }, + { + "time": 0.3333, + "value": 5.99, + "curve": [ 0.381, 1.72, 0.55, -11.11 ] + }, + { + "time": 0.6667, + "value": -11.11, + "curve": [ 0.833, -11.11, 0.933, 22.54 ] + }, + { + "time": 1.1, + "value": 22.54, + "curve": [ 1.158, 22.54, 1.275, -6.81 ] + }, + { "time": 1.3333, "value": -6.81 } + ] + }, + "torso2": { + "rotate": [ + { + "value": 4.52, + "curve": [ 0.013, 2.33, 0.092, -9.75 ] + }, + { + "time": 0.1333, + "value": -9.75, + "curve": [ 0.175, -9.75, 0.291, -1.26 ] + }, + { + "time": 0.3333, + "value": 0.96, + "curve": [ 0.359, 2.3, 0.543, 4.25 ] + }, + { + "time": 0.6, + "value": 4.68, + "curve": [ 0.683, 5.3, 0.771, 5.92 ] + }, + { + "time": 0.8333, + "value": 6.48, + "curve": [ 0.871, 6.82, 1.083, 11.37 ] + }, + { + "time": 1.1667, + "value": 11.37, + "curve": [ 1.208, 11.37, 1.317, 6.18 ] + }, + { "time": 1.3333, "value": 4.52 } + ], + "translate": [ + { + "curve": [ 0, 0, 0.082, -2.24, 0, 0, 0.082, -0.42 ] + }, + { + "time": 0.1667, + "x": -2.98, + "y": -0.56, + "curve": [ 0.232, -2.24, 0.298, 0, 0.232, -0.42, 0.298, 0 ] + }, + { "time": 0.3333, "curve": "stepped" }, + { + "time": 0.8667, + "curve": [ 0.889, 0, 0.912, 0.26, 0.889, 0, 0.912, 0.06 ] + }, + { + "time": 0.9333, + "x": 0.68, + "y": 0.23, + "curve": [ 1.016, 2.22, 1.095, 5.9, 1.023, 0.97, 1.095, 1.99 ] + }, + { + "time": 1.1667, + "x": 6.47, + "y": 2.18, + "curve": [ 1.23, 5.75, 1.286, 0, 1.23, 1.94, 1.286, 0 ] + }, + { "time": 1.3333 } + ] + }, + "torso3": { + "rotate": [ + { + "value": 4.52, + "curve": [ 0.025, 4.52, 0.075, -6.17 ] + }, + { + "time": 0.1, + "value": -6.17, + "curve": [ 0.175, -6.17, 0.381, -0.71 ] + }, + { + "time": 0.4, + "value": -0.25, + "curve": [ 0.447, 0.87, 0.775, 4.84 ] + }, + { + "time": 0.9, + "value": 4.84, + "curve": [ 1.008, 4.84, 1.225, 4.52 ] + }, + { "time": 1.3333, "value": 4.52 } + ] + }, + "head-control": { + "translate": [ + { + "curve": [ 0.138, -2.4, 0.227, -10.44, 0.123, 1.05, 0.227, 2.7 ] + }, + { + "time": 0.3667, + "x": -10.44, + "y": 2.7, + "curve": [ 0.484, -10.44, 0.585, -5.63, 0.484, 2.7, 0.629, -23.62 ] + }, + { + "time": 0.7333, + "x": -2.29, + "y": -26.61, + "curve": [ 0.818, -0.39, 0.962, 1.21, 0.858, -30.17, 0.972, -28.75 ] + }, + { + "time": 1.1, + "x": 1.25, + "y": -28.75, + "curve": [ 1.192, 1.28, 1.234, 0.98, 1.224, -28.75, 1.235, -2.15 ] + }, + { "time": 1.3333 } + ] + }, + "front-shoulder": { + "translate": [ + { + "curve": [ 0.031, -2.22, 0.065, -3.73, 0.02, -3.25, 0.065, -14.74 ] + }, + { + "time": 0.1, + "x": -3.73, + "y": -14.74, + "curve": [ 0.216, -3.73, 0.384, -0.17, 0.216, -14.74, 0.402, -12.51 ] + }, + { + "time": 0.5, + "x": 1.63, + "y": -9.51, + "curve": [ 0.632, 3.69, 0.935, 7.41, 0.585, -6.91, 0.909, 10.86 ] + }, + { + "time": 1.1, + "x": 7.45, + "y": 10.99, + "curve": [ 1.18, 7.46, 1.265, 2.86, 1.193, 11.05, 1.294, 3.38 ] + }, + { "time": 1.3333 } + ] + } + }, + "ik": { + "front-foot-ik": [ + { + "mix": 0, + "curve": [ 0.3, 0, 0.9, 1, 0.3, 0, 0.9, 0 ] + }, + { "time": 1.2 } + ], + "front-leg-ik": [ + { + "mix": 0, + "bendPositive": false, + "curve": [ 0.3, 0, 0.9, 1, 0.3, 0, 0.9, 0 ] + }, + { "time": 1.2, "bendPositive": false } + ], + "rear-foot-ik": [ + { "mix": 0 } + ], + "rear-leg-ik": [ + { "mix": 0, "bendPositive": false } + ] + }, + "events": [ + { "time": 1.2, "name": "footstep" } + ] + }, + "portal": { + "slots": { + "clipping": { + "attachment": [ + { "name": "clipping" } + ] + }, + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + }, + "mouth": { + "attachment": [ + { "time": 0.9, "name": "mouth-grind" }, + { "time": 2.2667, "name": "mouth-smile" } + ] + }, + "portal-bg": { + "attachment": [ + { "name": "portal-bg" }, + { "time": 3 } + ] + }, + "portal-flare1": { + "attachment": [ + { "time": 1.1, "name": "portal-flare1" }, + { "time": 1.1333, "name": "portal-flare2" }, + { "time": 1.1667, "name": "portal-flare3" }, + { "time": 1.2, "name": "portal-flare1" }, + { "time": 1.2333, "name": "portal-flare2" }, + { "time": 1.2667, "name": "portal-flare1" }, + { "time": 1.3333 } + ] + }, + "portal-flare2": { + "attachment": [ + { "time": 1.1, "name": "portal-flare2" }, + { "time": 1.1333, "name": "portal-flare3" }, + { "time": 1.1667, "name": "portal-flare1" }, + { "time": 1.2, "name": "portal-flare2" }, + { "time": 1.2333, "name": "portal-flare3" }, + { "time": 1.2667 } + ] + }, + "portal-flare3": { + "attachment": [ + { "time": 1.2, "name": "portal-flare3" }, + { "time": 1.2333, "name": "portal-flare2" }, + { "time": 1.2667 } + ] + }, + "portal-flare4": { + "attachment": [ + { "time": 1.2, "name": "portal-flare2" }, + { "time": 1.2333, "name": "portal-flare1" }, + { "time": 1.2667, "name": "portal-flare2" }, + { "time": 1.3333 } + ] + }, + "portal-flare5": { + "attachment": [ + { "time": 1.2333, "name": "portal-flare3" }, + { "time": 1.2667, "name": "portal-flare1" }, + { "time": 1.3333 } + ] + }, + "portal-flare6": { + "attachment": [ + { "time": 1.2667, "name": "portal-flare3" }, + { "time": 1.3333 } + ] + }, + "portal-flare7": { + "attachment": [ + { "time": 1.1333, "name": "portal-flare2" }, + { "time": 1.1667 } + ] + }, + "portal-flare8": { + "attachment": [ + { "time": 1.2, "name": "portal-flare3" }, + { "time": 1.2333, "name": "portal-flare2" }, + { "time": 1.2667 } + ] + }, + "portal-flare9": { + "attachment": [ + { "time": 1.2, "name": "portal-flare2" }, + { "time": 1.2333, "name": "portal-flare3" }, + { "time": 1.2667, "name": "portal-flare1" }, + { "time": 1.3 } + ] + }, + "portal-flare10": { + "attachment": [ + { "time": 1.2, "name": "portal-flare2" }, + { "time": 1.2333, "name": "portal-flare1" }, + { "time": 1.2667, "name": "portal-flare3" }, + { "time": 1.3 } + ] + }, + "portal-shade": { + "attachment": [ + { "name": "portal-shade" }, + { "time": 3 } + ] + }, + "portal-streaks1": { + "attachment": [ + { "name": "portal-streaks1" }, + { "time": 3 } + ] + }, + "portal-streaks2": { + "attachment": [ + { "name": "portal-streaks2" }, + { "time": 3 } + ] + } + }, + "bones": { + "portal-root": { + "translate": [ + { + "x": -458.35, + "y": 105.19, + "curve": [ 0.333, -458.22, 0.669, -457.86, 0.934, 105.19, 0.671, 105.19 ] + }, + { + "time": 1, + "x": -456.02, + "y": 105.19, + "curve": [ 1.339, -454.14, 2.208, -447.28, 1.35, 105.19, 2.05, 105.19 ] + }, + { + "time": 2.4, + "x": -439.12, + "y": 105.19, + "curve": [ 2.463, -436.44, 2.502, -432.92, 2.487, 105.19, 2.512, 105.09 ] + }, + { + "time": 2.6, + "x": -432.58, + "y": 105.09, + "curve": [ 2.784, -431.94, 2.978, -446.6, 2.772, 105.09, 2.933, 105.19 ] + }, + { "time": 3.0333, "x": -457.42, "y": 105.19 } + ], + "scale": [ + { + "x": 0.003, + "y": 0.006, + "curve": [ 0.329, 0.044, 0.347, 0.117, 0.329, 0.097, 0.37, 0.249 ] + }, + { + "time": 0.4, + "x": 0.175, + "y": 0.387, + "curve": [ 0.63, 0.619, 0.663, 0.723, 0.609, 1.338, 0.645, 1.524 ] + }, + { + "time": 0.7333, + "x": 0.724, + "y": 1.52, + "curve": [ 0.798, 0.725, 0.907, 0.647, 0.797, 1.517, 0.895, 1.424 ] + }, + { + "time": 1, + "x": 0.645, + "y": 1.426, + "curve": [ 1.095, 0.643, 1.139, 0.688, 1.089, 1.428, 1.115, 1.513 ] + }, + { + "time": 1.2333, + "x": 0.685, + "y": 1.516, + "curve": [ 1.325, 0.683, 1.508, 0.636, 1.343, 1.518, 1.467, 1.4 ] + }, + { + "time": 1.6, + "x": 0.634, + "y": 1.401, + "curve": [ 1.728, 0.631, 1.946, 0.687, 1.722, 1.402, 1.924, 1.522 ] + }, + { + "time": 2.0667, + "x": 0.688, + "y": 1.522, + "curve": [ 2.189, 0.69, 2.289, 0.649, 2.142, 1.522, 2.265, 1.417 ] + }, + { + "time": 2.4, + "x": 0.65, + "y": 1.426, + "curve": [ 2.494, 0.651, 2.504, 0.766, 2.508, 1.434, 2.543, 1.566 ] + }, + { + "time": 2.6, + "x": 0.766, + "y": 1.568, + "curve": [ 2.73, 0.765, 3.006, 0.098, 2.767, 1.564, 2.997, 0.1 ] + }, + { "time": 3.0333, "x": 0.007, "y": 0.015 } + ] + }, + "portal-streaks1": { + "rotate": [ + {}, + { "time": 3.1667, "value": 1200 } + ], + "translate": [ + { + "x": 15.15, + "curve": [ 0.162, 15.15, 0.432, 12.6, 0.162, 0, 0.432, -3.86 ] + }, + { + "time": 0.6667, + "x": 10.9, + "y": -6.44, + "curve": [ 0.794, 9.93, 0.912, 9.21, 0.794, -7.71, 0.912, -8.66 ] + }, + { + "time": 1, + "x": 9.21, + "y": -8.66, + "curve": [ 1.083, 9.21, 1.25, 21.53, 1.083, -8.66, 1.265, -4.9 ] + }, + { + "time": 1.3333, + "x": 21.53, + "y": -3.19, + "curve": [ 1.5, 21.53, 1.939, 12.3, 1.446, -0.37, 1.9, 6.26 ] + }, + { + "time": 2.0667, + "x": 11.26, + "y": 6.26, + "curve": [ 2.239, 9.85, 2.389, 9.68, 2.208, 6.26, 2.523, 0.51 ] + }, + { + "time": 2.5667, + "x": 9.39, + "y": -0.8, + "curve": [ 2.657, 9.24, 2.842, 9.21, 2.646, -3.2, 2.842, -8.91 ] + }, + { "time": 2.9333, "x": 9.21, "y": -8.91 } + ], + "scale": [ + { + "curve": [ 0.167, 1, 0.5, 1.053, 0.167, 1, 0.5, 1.053 ] + }, + { + "time": 0.6667, + "x": 1.053, + "y": 1.053, + "curve": [ 0.833, 1.053, 1.167, 0.986, 0.833, 1.053, 1.167, 0.986 ] + }, + { + "time": 1.3333, + "x": 0.986, + "y": 0.986, + "curve": [ 1.5, 0.986, 1.833, 1.053, 1.5, 0.986, 1.833, 1.053 ] + }, + { "time": 2, "x": 1.053, "y": 1.053 } + ] + }, + "portal-streaks2": { + "rotate": [ + {}, + { "time": 3.1667, "value": 600 } + ], + "translate": [ + { "x": -2.11 }, + { "time": 1, "x": -2.11, "y": 6.63 }, + { "time": 1.9333, "x": -2.11 } + ], + "scale": [ + { + "x": 1.014, + "y": 1.014, + "curve": [ 0.229, 0.909, 0.501, 0.755, 0.242, 0.892, 0.502, 0.768 ] + }, + { + "time": 0.8667, + "x": 0.745, + "y": 0.745, + "curve": [ 1.282, 0.733, 2.021, 0.699, 1.27, 0.719, 2.071, 0.709 ] + }, + { + "time": 2.2, + "x": 0.7, + "y": 0.704, + "curve": [ 2.315, 0.7, 2.421, 0.794, 2.311, 0.701, 2.485, 0.797 ] + }, + { + "time": 2.5667, + "x": 0.794, + "y": 0.794, + "curve": [ 2.734, 0.794, 2.99, 0.323, 2.714, 0.789, 3.019, 0.341 ] + }, + { "time": 3.1667, "x": 0, "y": 0 } + ] + }, + "portal-shade": { + "translate": [ + { "x": -29.68 } + ], + "scale": [ + { "x": 0.714, "y": 0.714 } + ] + }, + "portal": { + "rotate": [ + {}, + { "time": 3.1667, "value": 600 } + ] + }, + "clipping": { + "translate": [ + { "x": -476.55, "y": 2.27 } + ], + "scale": [ + { "x": 0.983, "y": 1.197 } + ] + }, + "hip": { + "rotate": [ + { + "time": 1.0667, + "value": 22.74, + "curve": [ 1.163, 18.84, 1.77, 8.77 ] + }, + { + "time": 1.9, + "value": 7.82, + "curve": [ 2.271, 5.1, 2.89, 0 ] + }, + { "time": 3.1667 } + ], + "translate": [ + { "x": -899.41, "y": 4.47, "curve": "stepped" }, + { + "time": 1.0667, + "x": -694.16, + "y": 183.28, + "curve": [ 1.091, -602.08, 1.138, -427.59, 1.115, 185.6, 1.171, 133.18 ] + }, + { + "time": 1.2333, + "x": -316.97, + "y": 55.29, + "curve": [ 1.317, -220.27, 1.512, -123.21, 1.271, 8.68, 1.461, -83.18 ] + }, + { + "time": 1.6, + "x": -95.53, + "y": -112.23, + "curve": [ 1.718, -58.25, 2.037, -22.54, 1.858, -166.17, 2.109, -31.4 ] + }, + { + "time": 2.1667, + "x": -14.82, + "y": -31.12, + "curve": [ 2.294, -7.28, 2.442, -7.2, 2.274, -30.6, 2.393, -36.76 ] + }, + { + "time": 2.6, + "x": -7.2, + "y": -36.96, + "curve": [ 2.854, -7.2, 3.071, -11.87, 2.786, -36.27, 3.082, -22.98 ] + }, + { "time": 3.1667, "x": -11.97, "y": -23.15 } + ] + }, + "rear-foot-target": { + "rotate": [ + { "time": 1.0667, "value": 41.6, "curve": "stepped" }, + { + "time": 1.2333, + "value": 41.6, + "curve": [ 1.258, 41.6, 1.379, 35.46 ] + }, + { + "time": 1.4, + "value": 30.09, + "curve": [ 1.412, 27.04, 1.433, 10.65 ] + }, + { "time": 1.4333, "value": -0.28 }, + { "time": 1.6, "value": 2.44 } + ], + "translate": [ + { "x": -899.41, "y": 4.47, "curve": "stepped" }, + { + "time": 1.0667, + "x": -591.13, + "y": 438.46, + "curve": [ 1.076, -539.77, 1.206, -268.1, 1.117, 418.44, 1.21, 333.18 ] + }, + { + "time": 1.2333, + "x": -225.28, + "y": 304.53, + "curve": [ 1.265, -175.22, 1.393, -74.21, 1.296, 226.52, 1.401, 49.61 ] + }, + { + "time": 1.4333, + "x": -52.32, + "y": 0.2, + "curve": [ 1.454, -40.85, 1.616, 40.87, 1.466, 0.17, 1.614, 0.04 ] + }, + { "time": 1.6667, "x": 45.87, "y": 0.01 }, + { "time": 1.9333, "x": 48.87 } + ] + }, + "front-foot-target": { + "rotate": [ + { + "time": 1.0667, + "value": 32.08, + "curve": [ 1.108, 32.08, 1.192, 35.16 ] + }, + { + "time": 1.2333, + "value": 35.16, + "curve": [ 1.258, 35.16, 1.317, 2.23 ] + }, + { + "time": 1.3333, + "value": -4.74, + "curve": [ 1.351, -12.14, 1.429, -34.96 ] + }, + { + "time": 1.6, + "value": -34.77, + "curve": [ 1.765, -34.58, 1.897, -17.25 ] + }, + { "time": 1.9333 } + ], + "translate": [ + { "x": -899.41, "y": 4.47, "curve": "stepped" }, + { + "time": 1.0667, + "x": -533.93, + "y": 363.75, + "curve": [ 1.074, -480.85, 1.18, -261.31, 1.094, 362.3, 1.195, 267.77 ] + }, + { + "time": 1.2333, + "x": -201.23, + "y": 199.93, + "curve": [ 1.269, -161.38, 1.294, -140.32, 1.274, 126.67, 1.308, 77.12 ] + }, + { + "time": 1.3333, + "x": -124.08, + "y": 0.2, + "curve": [ 1.426, -85.6, 1.633, -69.06, 1.45, 0.48, 1.633, 0 ] + }, + { "time": 1.7333, "x": -69.06 } + ] + }, + "torso": { + "rotate": [ + { + "time": 1.0667, + "value": 27.02, + "curve": [ 1.187, 26.86, 1.291, 7.81 ] + }, + { + "time": 1.3333, + "value": -2.62, + "curve": [ 1.402, -19.72, 1.429, -48.64 ] + }, + { + "time": 1.4667, + "value": -56.31, + "curve": [ 1.509, -64.87, 1.62, -77.14 ] + }, + { + "time": 1.7333, + "value": -77.34, + "curve": [ 1.837, -76.89, 1.895, -71.32 ] + }, + { + "time": 2, + "value": -57.52, + "curve": [ 2.104, -43.83, 2.189, -28.59 ] + }, + { + "time": 2.3, + "value": -29.03, + "curve": [ 2.413, -29.48, 2.513, -36.79 ] + }, + { + "time": 2.6667, + "value": -36.79, + "curve": [ 2.814, -36.95, 2.947, -22.88 ] + }, + { "time": 3.1667, "value": -22.88 } + ] + }, + "neck": { + "rotate": [ + { + "time": 1.0667, + "value": -3.57, + "curve": [ 1.146, -3.66, 1.15, -13.5 ] + }, + { + "time": 1.2333, + "value": -13.5, + "curve": [ 1.428, -13.5, 1.443, 11.58 ] + }, + { + "time": 1.5667, + "value": 11.42, + "curve": [ 1.658, 11.3, 1.775, 3.78 ] + }, + { + "time": 1.8667, + "value": 3.78, + "curve": [ 1.92, 3.78, 2.036, 8.01 ] + }, + { + "time": 2.1, + "value": 7.93, + "curve": [ 2.266, 7.72, 2.42, 3.86 ] + }, + { + "time": 2.5333, + "value": 3.86, + "curve": [ 2.783, 3.86, 3.004, 3.78 ] + }, + { "time": 3.1667, "value": 3.78 } + ] + }, + "head": { + "rotate": [ + { + "time": 1.0667, + "value": 16.4, + "curve": [ 1.133, 9.9, 1.207, 1.87 ] + }, + { + "time": 1.3333, + "value": 1.67, + "curve": [ 1.46, 1.56, 1.547, 47.54 ] + }, + { + "time": 1.7333, + "value": 47.55, + "curve": [ 1.897, 47.56, 2.042, 5.68 ] + }, + { + "time": 2.0667, + "value": 0.86, + "curve": [ 2.074, -0.61, 2.086, -2.81 ] + }, + { + "time": 2.1, + "value": -5.31, + "curve": [ 2.145, -13.07, 2.216, -23.65 ] + }, + { + "time": 2.2667, + "value": -23.71, + "curve": [ 2.334, -23.79, 2.426, -13.43 ] + }, + { + "time": 2.4667, + "value": -9.18, + "curve": [ 2.498, -5.91, 2.604, 2.53 ] + }, + { + "time": 2.6667, + "value": 2.52, + "curve": [ 2.738, 2.24, 2.85, -8.76 ] + }, + { + "time": 2.9333, + "value": -8.67, + "curve": [ 3.036, -8.55, 3.09, -7.09 ] + }, + { "time": 3.1667, "value": -6.75 } + ], + "scale": [ + { + "time": 1.3333, + "curve": [ 1.392, 1, 1.526, 1, 1.392, 1, 1.508, 1.043 ] + }, + { + "time": 1.5667, + "x": 0.992, + "y": 1.043, + "curve": [ 1.598, 0.985, 1.676, 0.955, 1.584, 1.043, 1.672, 1.04 ] + }, + { + "time": 1.7333, + "x": 0.954, + "y": 1.029, + "curve": [ 1.843, 0.954, 1.933, 1, 1.825, 1.013, 1.933, 1 ] + }, + { "time": 2 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "time": 0.9, + "value": 39.24, + "curve": [ 0.968, 39.93, 1.267, 85.31 ] + }, + { + "time": 1.4667, + "value": 112.27, + "curve": [ 1.555, 124.24, 1.576, 126.44 ] + }, + { + "time": 1.6333, + "value": 126.44, + "curve": [ 1.782, 126.44, 1.992, 94.55 ] + }, + { + "time": 2.1, + "value": 79.96, + "curve": [ 2.216, 64.26, 2.407, 34.36 ] + }, + { + "time": 2.5667, + "value": 33.38, + "curve": [ 2.815, 31.87, 3.1, 39.2 ] + }, + { "time": 3.1667, "value": 39.2 } + ] + }, + "back-foot-tip": { + "rotate": [ + { + "time": 1.0667, + "value": 56.07, + "curve": [ 1.138, 59.21, 1.192, 59.65 ] + }, + { + "time": 1.2333, + "value": 59.46, + "curve": [ 1.295, 59.17, 1.45, 22.54 ] + }, + { "time": 1.4667, "value": -0.84 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "time": 1.0667, + "value": 118.03, + "curve": [ 1.075, 93.64, 1.358, -34.03 ] + }, + { + "time": 1.6667, + "value": -33.94, + "curve": [ 1.808, -33.89, 1.879, -25 ] + }, + { + "time": 1.9667, + "value": -25.19, + "curve": [ 2.09, -25.46, 2.312, -34.58 ] + }, + { + "time": 2.3667, + "value": -38.36, + "curve": [ 2.465, -45.18, 2.557, -60.1 ] + }, + { + "time": 2.8333, + "value": -61.1, + "curve": [ 2.843, -61.06, 3.16, -60.87 ] + }, + { "time": 3.1667, "value": -60.87 } + ] + }, + "front-bracer": { + "rotate": [ + { + "time": 1.0667, + "value": 0.66, + "curve": [ 1.108, 0.66, 1.221, 44.95 ] + }, + { + "time": 1.2333, + "value": 49.25, + "curve": [ 1.263, 59.42, 1.342, 68.06 ] + }, + { + "time": 1.3667, + "value": 68.34, + "curve": [ 1.409, 68.8, 1.476, 4.9 ] + }, + { + "time": 1.5, + "value": -2.05, + "curve": [ 1.529, -10.3, 1.695, -15.95 ] + }, + { + "time": 1.7333, + "value": -17.38, + "curve": [ 1.807, -20.1, 1.878, -21.19 ] + }, + { + "time": 1.9333, + "value": -21.08, + "curve": [ 2.073, -20.8, 2.146, -7.63 ] + }, + { + "time": 2.1667, + "value": -3.64, + "curve": [ 2.186, 0.12, 2.275, 15.28 ] + }, + { + "time": 2.3333, + "value": 21.78, + "curve": [ 2.392, 28.31, 2.575, 37.66 ] + }, + { + "time": 2.7, + "value": 39.43, + "curve": [ 2.947, 42.93, 3.02, 42.46 ] + }, + { "time": 3.1667, "value": 42.46 } + ] + }, + "front-thigh": { + "translate": [ + { "time": 1.1, "x": -6.41, "y": 18.23, "curve": "stepped" }, + { "time": 1.1333, "x": -6.41, "y": 18.23 }, + { "time": 1.2, "x": 1.61, "y": 3.66 }, + { "time": 1.2333, "x": 4.5, "y": -3.15 }, + { "time": 1.3667, "x": -3.79, "y": 2.94 }, + { "time": 1.4, "x": -8.37, "y": 8.72 }, + { "time": 1.4333, "x": -11.26, "y": 16.99 }, + { "time": 1.4667, "x": -9.89, "y": 24.73, "curve": "stepped" }, + { "time": 1.8667, "x": -9.89, "y": 24.73 }, + { "time": 2.1 } + ] + }, + "front-foot-tip": { + "rotate": [ + { "time": 1.0667, "value": 42.55, "curve": "stepped" }, + { "time": 1.1333, "value": 42.55 }, + { "time": 1.2333, "value": 17.71 }, + { "time": 1.3667, "value": 3.63 }, + { "time": 1.4333 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "time": 1.0667, + "value": 108.71, + "curve": [ 1.082, 108.29, 1.437, 50.73 ] + }, + { + "time": 1.5667, + "value": 24.87, + "curve": [ 1.62, 14.2, 1.66, -11.74 ] + }, + { + "time": 1.7333, + "value": -11.74, + "curve": [ 1.961, -11.73, 2.172, 1.66 ] + }, + { + "time": 2.2667, + "value": 7.88, + "curve": [ 2.331, 12.13, 2.439, 18.65 ] + }, + { + "time": 2.5333, + "value": 18.72, + "curve": [ 2.788, 18.91, 3.145, -0.3 ] + }, + { "time": 3.1667 } + ] + }, + "front-fist": { + "rotate": [ + { + "time": 1.1, + "value": 6.32, + "curve": [ 1.11, 3.31, 1.153, -5.07 ] + }, + { + "time": 1.2333, + "value": -5.13, + "curve": [ 1.311, -5.19, 1.364, 34.65 ] + }, + { + "time": 1.4667, + "value": 34.53, + "curve": [ 1.574, 34.41, 1.547, -55.78 ] + }, + { + "time": 1.8667, + "value": -54.7, + "curve": [ 1.947, -54.7, 2.03, -53.94 ] + }, + { + "time": 2.1333, + "value": -42.44, + "curve": [ 2.215, -33.42, 2.358, -4.43 ] + }, + { + "time": 2.4, + "value": 0.03, + "curve": [ 2.444, 4.66, 2.536, 8.2 ] + }, + { + "time": 2.6333, + "value": 8.2, + "curve": [ 2.733, 8.19, 2.804, -0.67 ] + }, + { + "time": 2.9, + "value": -0.82, + "curve": [ 3.127, -1.16, 3.093, 0 ] + }, + { "time": 3.1667 } + ] + }, + "gun": { + "rotate": [ + { + "time": 1.2667, + "curve": [ 1.35, 0, 1.549, 7.49 ] + }, + { + "time": 1.6, + "value": 9.5, + "curve": [ 1.663, 12.02, 1.846, 19.58 ] + }, + { + "time": 1.9333, + "value": 19.43, + "curve": [ 1.985, 19.4, 2.057, 2.98 ] + }, + { + "time": 2.2, + "value": 2.95, + "curve": [ 2.304, 3.55, 2.458, 10.8 ] + }, + { + "time": 2.5, + "value": 10.8, + "curve": [ 2.642, 10.8, 2.873, -2.54 ] + }, + { + "time": 2.9333, + "value": -2.55, + "curve": [ 3.09, -2.57, 3.08, 0 ] + }, + { "time": 3.1667 } + ] + }, + "hair2": { + "rotate": [ + { + "time": 1.0667, + "value": 26.19, + "curve": [ 1.158, 26.19, 1.368, 26 ] + }, + { + "time": 1.4333, + "value": 24.43, + "curve": [ 1.534, 22.03, 2, -29.14 ] + }, + { + "time": 2.2, + "value": -29.14, + "curve": [ 2.292, -29.14, 2.475, 6.71 ] + }, + { + "time": 2.5667, + "value": 6.71, + "curve": [ 2.675, 6.71, 2.814, -5.06 ] + }, + { + "time": 2.9, + "value": -5.06, + "curve": [ 2.973, -5.06, 3.123, 0 ] + }, + { "time": 3.1667 } + ] + }, + "hair4": { + "rotate": [ + { + "time": 1.0667, + "value": 5.21, + "curve": [ 1.108, 5.21, 1.192, 26.19 ] + }, + { + "time": 1.2333, + "value": 26.19, + "curve": [ 1.317, 26.19, 1.483, 10.63 ] + }, + { + "time": 1.5667, + "value": 10.63, + "curve": [ 1.627, 10.63, 1.642, 17.91 ] + }, + { + "time": 1.7, + "value": 17.94, + "curve": [ 1.761, 17.97, 1.774, 8.22 ] + }, + { + "time": 1.8, + "value": 3.33, + "curve": [ 1.839, -4.21, 1.95, -22.67 ] + }, + { + "time": 2, + "value": -22.67, + "curve": [ 2.025, -22.67, 2.123, -21.86 ] + }, + { + "time": 2.1667, + "value": -18.71, + "curve": [ 2.228, -14.31, 2.294, -0.3 ] + }, + { + "time": 2.3667, + "value": 6.36, + "curve": [ 2.433, 12.45, 2.494, 19.21 ] + }, + { + "time": 2.6, + "value": 19.21, + "curve": [ 2.729, 19.21, 2.854, 6.75 ] + }, + { + "time": 2.9333, + "value": 4.62, + "curve": [ 3.09, 0.45, 3.062, 0 ] + }, + { "time": 3.1667 } + ] + }, + "hair3": { + "rotate": [ + { + "time": 1.4333, + "curve": [ 1.45, 0, 1.452, 11.29 ] + }, + { + "time": 1.5, + "value": 11.21, + "curve": [ 1.596, 11.06, 1.573, -14.17 ] + }, + { + "time": 1.7333, + "value": -20.4, + "curve": [ 1.851, -24.98, 1.943, -28.45 ] + }, + { + "time": 2.2, + "value": -28.75, + "curve": [ 2.317, -28.75, 2.55, 7.04 ] + }, + { + "time": 2.6667, + "value": 7.04, + "curve": [ 2.792, 7.04, 2.885, -5.19 ] + }, + { + "time": 2.9667, + "value": -5.19, + "curve": [ 3.037, -5.19, 3.096, 0 ] + }, + { "time": 3.1667 } + ] + }, + "hair1": { + "rotate": [ + { + "time": 1.2333, + "curve": [ 1.283, 0, 1.349, 3.99 ] + }, + { + "time": 1.4333, + "value": 6.58, + "curve": [ 1.497, 8.54, 1.683, 9.35 ] + }, + { + "time": 1.7667, + "value": 9.35, + "curve": [ 1.825, 9.35, 1.945, -8.71 ] + }, + { + "time": 2, + "value": -11.15, + "curve": [ 2.058, -13.71, 2.2, -14.97 ] + }, + { + "time": 2.2667, + "value": -14.97, + "curve": [ 2.367, -14.97, 2.567, 18.77 ] + }, + { + "time": 2.6667, + "value": 18.77, + "curve": [ 2.733, 18.77, 2.817, 8.29 ] + }, + { + "time": 2.8667, + "value": 6.51, + "curve": [ 2.988, 2.17, 3.058, 0 ] + }, + { "time": 3.1667 } + ] + }, + "flare1": { + "rotate": [ + { "time": 1.1, "value": 8.2 } + ], + "translate": [ + { "time": 1.1, "x": -19.97, "y": 149.68 }, + { "time": 1.2, "x": 3.85, "y": 152.43 }, + { "time": 1.2333, "x": -15.42, "y": 152.29 } + ], + "scale": [ + { + "time": 1.1, + "x": 0.805, + "y": 0.805, + "curve": [ 1.119, 0.763, 1.16, 1.162, 1.117, 0.805, 1.15, 0.605 ] + }, + { + "time": 1.1667, + "x": 1.279, + "y": 0.605, + "curve": [ 1.177, 1.47, 1.192, 2.151, 1.175, 0.605, 1.192, 0.911 ] + }, + { + "time": 1.2, + "x": 2.151, + "y": 0.911, + "curve": [ 1.208, 2.151, 1.231, 1.668, 1.208, 0.911, 1.227, 0.844 ] + }, + { + "time": 1.2333, + "x": 1.608, + "y": 0.805, + "curve": [ 1.249, 1.205, 1.283, 0.547, 1.254, 0.685, 1.283, 0.416 ] + }, + { "time": 1.3, "x": 0.547, "y": 0.416 } + ], + "shear": [ + { "time": 1.1, "y": 4.63 }, + { "time": 1.2333, "x": -5.74, "y": 4.63 } + ] + }, + "flare2": { + "rotate": [ + { "time": 1.1, "value": 12.29 } + ], + "translate": [ + { "time": 1.1, "x": -8.63, "y": 132.96 }, + { "time": 1.2, "x": 4.35, "y": 132.93 } + ], + "scale": [ + { "time": 1.1, "x": 0.864, "y": 0.864 }, + { "time": 1.1667, "x": 0.945, "y": 0.945 }, + { "time": 1.2, "x": 1.511, "y": 1.081 } + ], + "shear": [ + { "time": 1.1, "y": 24.03 } + ] + }, + "flare3": { + "rotate": [ + { "time": 1.1667, "value": 2.88 } + ], + "translate": [ + { "time": 1.1667, "x": 3.24, "y": 114.81 } + ], + "scale": [ + { "time": 1.1667, "x": 0.668, "y": 0.668 } + ], + "shear": [ + { "time": 1.1667, "y": 38.59 } + ] + }, + "flare4": { + "rotate": [ + { "time": 1.1667, "value": -8.64 } + ], + "translate": [ + { "time": 1.1667, "x": -3.82, "y": 194.06 }, + { "time": 1.2667, "x": -1.82, "y": 198.47, "curve": "stepped" }, + { "time": 1.3, "x": -1.94, "y": 187.81 } + ], + "scale": [ + { "time": 1.1667, "x": 0.545, "y": 0.545 }, + { "time": 1.2667, "x": 0.757, "y": 0.757 } + ], + "shear": [ + { "time": 1.1667, "x": 7.42, "y": -22.04 } + ] + }, + "flare5": { + "translate": [ + { "time": 1.2, "x": -11.17, "y": 176.42 }, + { "time": 1.2333, "x": -8.56, "y": 179.04, "curve": "stepped" }, + { "time": 1.3, "x": -14.57, "y": 168.69 } + ], + "scale": [ + { "time": 1.2333, "x": 1.146 }, + { "time": 1.3, "x": 0.703, "y": 0.61 } + ], + "shear": [ + { "time": 1.2, "x": 6.9 } + ] + }, + "flare6": { + "rotate": [ + { "time": 1.2333, "value": -5.36 }, + { "time": 1.2667, "value": -0.54 } + ], + "translate": [ + { "time": 1.2333, "x": 14.52, "y": 204.67 }, + { "time": 1.2667, "x": 19.16, "y": 212.9, "curve": "stepped" }, + { "time": 1.3, "x": 9.23, "y": 202.85 } + ], + "scale": [ + { "time": 1.2333, "x": 0.777, "y": 0.49 }, + { "time": 1.2667, "x": 0.777, "y": 0.657 }, + { "time": 1.3, "x": 0.475, "y": 0.401 } + ] + }, + "flare7": { + "rotate": [ + { "time": 1.1, "value": 5.98 }, + { "time": 1.1333, "value": 32.82 } + ], + "translate": [ + { "time": 1.1, "x": -6.34, "y": 112.98 }, + { "time": 1.1333, "x": 2.66, "y": 111.6 } + ], + "scale": [ + { "time": 1.1, "x": 0.588, "y": 0.588 } + ], + "shear": [ + { "time": 1.1333, "x": -19.93 } + ] + }, + "flare8": { + "rotate": [ + { "time": 1.2333, "value": -6.85 } + ], + "translate": [ + { "time": 1.1667, "x": 66.67, "y": 125.52, "curve": "stepped" }, + { "time": 1.2, "x": 58.24, "y": 113.53, "curve": "stepped" }, + { "time": 1.2333, "x": 40.15, "y": 114.69 } + ], + "scale": [ + { "time": 1.1667, "x": 1.313, "y": 1.203 }, + { "time": 1.2333, "x": 1.038, "y": 0.95 } + ], + "shear": [ + { "time": 1.2, "y": -13.01 } + ] + }, + "flare9": { + "rotate": [ + { "time": 1.1667, "value": 2.9 } + ], + "translate": [ + { "time": 1.1667, "x": 28.45, "y": 151.35, "curve": "stepped" }, + { "time": 1.2, "x": 48.8, "y": 191.09, "curve": "stepped" }, + { "time": 1.2333, "x": 52, "y": 182.52, "curve": "stepped" }, + { "time": 1.2667, "x": 77.01, "y": 195.96 } + ], + "scale": [ + { "time": 1.1667, "x": 0.871, "y": 1.073 }, + { "time": 1.2, "x": 0.927, "y": 0.944 }, + { "time": 1.2333, "x": 1.165, "y": 1.336 } + ], + "shear": [ + { "time": 1.1667, "x": 7.95, "y": 25.48 } + ] + }, + "flare10": { + "rotate": [ + { "time": 1.1667, "value": 2.18 } + ], + "translate": [ + { "time": 1.1667, "x": 55.64, "y": 137.64, "curve": "stepped" }, + { "time": 1.2, "x": 90.49, "y": 151.07, "curve": "stepped" }, + { "time": 1.2333, "x": 114.06, "y": 153.05, "curve": "stepped" }, + { "time": 1.2667, "x": 90.44, "y": 164.61 } + ], + "scale": [ + { "time": 1.1667, "x": 2.657, "y": 0.891 }, + { "time": 1.2, "x": 3.314, "y": 1.425 }, + { "time": 1.2333, "x": 2.871, "y": 0.924 }, + { "time": 1.2667, "x": 2.317, "y": 0.775 } + ], + "shear": [ + { "time": 1.1667, "x": -1.35 } + ] + }, + "torso2": { + "rotate": [ + { + "time": 1, + "curve": [ 1.117, 0, 1.255, 24.94 ] + }, + { + "time": 1.4, + "value": 24.94, + "curve": [ 1.477, 24.94, 1.59, -17.62 ] + }, + { + "time": 1.6333, + "value": -19.48, + "curve": [ 1.717, -23.1, 1.784, -26.12 ] + }, + { + "time": 1.9333, + "value": -26.14, + "curve": [ 2.067, -26.15, 2.158, 4.3 ] + }, + { + "time": 2.3, + "value": 4.22, + "curve": [ 2.45, 4.13, 2.579, -1.76 ] + }, + { + "time": 2.7333, + "value": -1.8, + "curve": [ 2.816, -1.82, 2.857, -2.94 ] + }, + { + "time": 2.9333, + "value": -2.99, + "curve": [ 3.056, -3.08, 3.09, 0 ] + }, + { "time": 3.1667 } + ] + }, + "torso3": { + "rotate": [ + { + "time": 1.3, + "curve": [ 1.352, 0, 1.408, 6.47 ] + }, + { + "time": 1.4667, + "value": 6.43, + "curve": [ 1.55, 6.39, 1.723, -5.05 ] + }, + { + "time": 1.7333, + "value": -5.53, + "curve": [ 1.782, -7.72, 1.843, -16.94 ] + }, + { + "time": 1.9667, + "value": -16.86, + "curve": [ 2.111, -16.78, 2.259, -3.97 ] + }, + { + "time": 2.4, + "value": -2.43, + "curve": [ 2.525, -1.12, 2.639, -0.5 ] + }, + { + "time": 2.7333, + "value": -0.49, + "curve": [ 2.931, -0.47, 2.999, -2.15 ] + }, + { "time": 3.1667, "value": -2.15 } + ] + }, + "head-control": { + "translate": [ + { + "time": 1.2333, + "curve": [ 1.25, 0, 1.474, 6.89, 1.25, 0, 1.496, 0.98 ] + }, + { + "time": 1.6667, + "x": 11.99, + "y": -6.42, + "curve": [ 1.743, 14.01, 1.86, 14.33, 1.785, -11.55, 1.86, -27.1 ] + }, + { + "time": 1.9667, + "x": 13.91, + "y": -26.88, + "curve": [ 2.074, 13.49, 2.244, 8.13, 2.074, -26.65, 2.215, -21.78 ] + }, + { + "time": 2.3, + "x": 6.07, + "y": -16.64, + "curve": [ 2.416, 1.84, 2.497, -1.41, 2.417, -9.57, 2.526, -1.72 ] + }, + { + "time": 2.5667, + "x": -3.78, + "y": -1.71, + "curve": [ 2.661, -6.98, 2.76, -8.76, 2.692, -1.68, 2.821, -15.75 ] + }, + { + "time": 2.9, + "x": -8.32, + "y": -16.7, + "curve": [ 2.962, -8.12, 3.082, -0.04, 2.958, -17.39, 3.089, 0 ] + }, + { "time": 3.1667 } + ] + }, + "front-shoulder": { + "translate": [ + { + "time": 1.3333, + "curve": [ 1.488, 0, 1.717, 0.21, 1.488, 0, 1.688, -30.29 ] + }, + { + "time": 1.9, + "x": 0.83, + "y": -30.29, + "curve": [ 2.078, 1.43, 2.274, 2.88, 2.071, -30.29, 2.289, 4.48 ] + }, + { + "time": 2.4333, + "x": 2.89, + "y": 4.59, + "curve": [ 2.604, 2.89, 2.677, -0.68, 2.57, 4.7, 2.694, -2.43 ] + }, + { + "time": 2.7667, + "x": -0.67, + "y": -2.47, + "curve": [ 2.866, -0.67, 2.986, -0.07, 2.882, -2.47, 3.036, -0.06 ] + }, + { "time": 3.1667 } + ] + } + }, + "ik": { + "rear-leg-ik": [ + { "time": 3.1667, "softness": 10, "bendPositive": false } + ] + } + }, + "run": { + "slots": { + "mouth": { + "attachment": [ + { "name": "mouth-grind" } + ] + } + }, + "bones": { + "front-thigh": { + "translate": [ + { + "x": -5.14, + "y": 11.13, + "curve": [ 0.033, -7.77, 0.112, -9.03, 0.034, 11.13, 0.108, 9.74 ] + }, + { + "time": 0.1667, + "x": -9.03, + "y": 7.99, + "curve": [ 0.23, -9.05, 0.314, -1.34, 0.236, 5.93, 0.28, 3.22 ] + }, + { + "time": 0.3333, + "x": 0.41, + "y": 3.19, + "curve": [ 0.352, 2.09, 0.449, 11.16, 0.384, 3.16, 0.449, 4.98 ] + }, + { + "time": 0.5, + "x": 11.17, + "y": 6.76, + "curve": [ 0.571, 10.79, 0.621, -1.83, 0.542, 8.21, 0.625, 11.13 ] + }, + { "time": 0.6667, "x": -5.14, "y": 11.13 } + ] + }, + "torso": { + "rotate": [ + { + "value": -37.66, + "curve": [ 0.034, -37.14, 0.107, -36.21 ] + }, + { + "time": 0.1333, + "value": -36.21, + "curve": [ 0.158, -36.21, 0.209, -38.8 ] + }, + { + "time": 0.2333, + "value": -38.79, + "curve": [ 0.259, -38.78, 0.313, -38.03 ] + }, + { + "time": 0.3333, + "value": -37.66, + "curve": [ 0.357, -37.21, 0.4, -36.21 ] + }, + { + "time": 0.4333, + "value": -36.21, + "curve": [ 0.458, -36.21, 0.539, -38.8 ] + }, + { + "time": 0.5667, + "value": -38.8, + "curve": [ 0.592, -38.8, 0.645, -38 ] + }, + { "time": 0.6667, "value": -37.66 } + ] + }, + "rear-thigh": { + "translate": [ + { + "x": -16.41, + "y": 1.55, + "curve": [ 0.013, -15.67, 0.183, -8.55, 0.03, 2.39, 0.183, 6.17 ] + }, + { + "time": 0.2333, + "x": -8.55, + "y": 6.17, + "curve": [ 0.308, -8.55, 0.492, -19.75, 0.308, 6.17, 0.492, 0.61 ] + }, + { + "time": 0.5667, + "x": -19.75, + "y": 0.61, + "curve": [ 0.592, -19.75, 0.641, -18.06, 0.592, 0.61, 0.632, 0.78 ] + }, + { "time": 0.6667, "x": -16.41, "y": 1.55 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -39.03, + "curve": [ 0.051, -0.1, 0.145, 88.36 ] + }, + { + "time": 0.2333, + "value": 88.36, + "curve": [ 0.28, 88.76, 0.324, 59.52 ] + }, + { + "time": 0.3333, + "value": 51.13, + "curve": [ 0.358, 30.2, 0.445, -74.91 ] + }, + { + "time": 0.5667, + "value": -75.82, + "curve": [ 0.599, -76.06, 0.642, -55.72 ] + }, + { "time": 0.6667, "value": -39.03 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 20.54, + "curve": [ 0.052, 11.42, 0.089, 0.13 ] + }, + { + "time": 0.1333, + "value": 0.15, + "curve": [ 0.186, 0.17, 0.221, 26.29 ] + }, + { + "time": 0.2333, + "value": 32.37, + "curve": [ 0.247, 39.19, 0.286, 61.45 ] + }, + { + "time": 0.3333, + "value": 61.58, + "curve": [ 0.371, 61.69, 0.42, 55.79 ] + }, + { "time": 0.4667, "value": 49.68 }, + { "time": 0.6667, "value": 20.54 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -36.16, + "curve": [ 0.014, -38.8, 0.036, -43.27 ] + }, + { + "time": 0.0667, + "value": -43.37, + "curve": [ 0.102, -43.49, 0.182, -28.46 ] + }, + { + "time": 0.2, + "value": -23.04, + "curve": [ 0.23, -13.87, 0.264, 3.86 ] + }, + { + "time": 0.3333, + "value": 3.7, + "curve": [ 0.38, 3.64, 0.535, -16.22 ] + }, + { "time": 0.5667, "value": -21.29 }, + { "time": 0.6667, "value": -36.16 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 40.5, + "curve": [ 0.028, 23.74, 0.128, -79.86 ] + }, + { + "time": 0.2333, + "value": -79.87, + "curve": [ 0.38, -79.88, 0.403, 63.25 ] + }, + { + "time": 0.5667, + "value": 64.13, + "curve": [ 0.607, 64.35, 0.644, 53.1 ] + }, + { "time": 0.6667, "value": 40.5 } + ], + "translate": [ + { + "x": -3.79, + "y": -0.77, + "curve": [ 0.044, -4.58, 0.169, -5.48, 0.044, 0.93, 0.169, 2.85 ] + }, + { + "time": 0.2333, + "x": -5.48, + "y": 2.85, + "curve": [ 0.346, -5.48, 0.475, -2.68, 0.346, 2.85, 0.475, -3.13 ] + }, + { + "time": 0.5667, + "x": -2.68, + "y": -3.13, + "curve": [ 0.611, -2.68, 0.642, -3.34, 0.611, -3.13, 0.642, -1.73 ] + }, + { "time": 0.6667, "x": -3.79, "y": -0.77 } + ] + }, + "rear-bracer": { + "rotate": [ + { "value": 28.28 }, + { + "time": 0.2333, + "value": -11.12, + "curve": [ 0.252, -14.12, 0.297, -19.37 ] + }, + { + "time": 0.3333, + "value": -19.38, + "curve": [ 0.435, -19.41, 0.522, 38.96 ] + }, + { + "time": 0.5667, + "value": 38.87, + "curve": [ 0.619, 38.76, 0.644, 32.01 ] + }, + { "time": 0.6667, "value": 28.28 } + ] + }, + "neck": { + "rotate": [ + { + "value": 11.88, + "curve": [ 0.024, 11.4, 0.075, 9.74 ] + }, + { + "time": 0.1, + "value": 9.74, + "curve": [ 0.125, 9.74, 0.208, 13.36 ] + }, + { + "time": 0.2333, + "value": 13.36, + "curve": [ 0.258, 13.36, 0.321, 12.2 ] + }, + { + "time": 0.3333, + "value": 11.88, + "curve": [ 0.365, 11.06, 0.408, 9.72 ] + }, + { + "time": 0.4333, + "value": 9.72, + "curve": [ 0.458, 9.72, 0.542, 13.36 ] + }, + { + "time": 0.5667, + "value": 13.36, + "curve": [ 0.592, 13.36, 0.636, 12.48 ] + }, + { "time": 0.6667, "value": 11.88 } + ] + }, + "head": { + "rotate": [ + { + "value": 13.14, + "curve": [ 0.02, 11.99, 0.039, 8.94 ] + }, + { + "time": 0.0667, + "value": 8.93, + "curve": [ 0.122, 8.9, 0.232, 15.8 ] + }, + { + "time": 0.2667, + "value": 15.81, + "curve": [ 0.325, 15.82, 0.357, 8.95 ] + }, + { + "time": 0.4, + "value": 8.93, + "curve": [ 0.444, 8.91, 0.568, 15.8 ] + }, + { + "time": 0.6, + "value": 15.77, + "curve": [ 0.632, 15.74, 0.649, 14.05 ] + }, + { "time": 0.6667, "value": 13.14 } + ], + "scale": [ + { + "curve": [ 0.014, 0.996, 0.068, 0.991, 0.027, 1.005, 0.083, 1.012 ] + }, + { + "time": 0.1, + "x": 0.991, + "y": 1.012, + "curve": [ 0.128, 0.991, 0.205, 1.018, 0.128, 1.012, 0.197, 0.988 ] + }, + { + "time": 0.2333, + "x": 1.018, + "y": 0.988, + "curve": [ 0.272, 1.018, 0.305, 1.008, 0.262, 0.988, 0.311, 0.995 ] + }, + { + "time": 0.3333, + "curve": [ 0.351, 0.995, 0.417, 0.987, 0.359, 1.006, 0.417, 1.013 ] + }, + { + "time": 0.4333, + "x": 0.987, + "y": 1.013, + "curve": [ 0.467, 0.987, 0.533, 1.02, 0.467, 1.013, 0.533, 0.989 ] + }, + { + "time": 0.5667, + "x": 1.02, + "y": 0.989, + "curve": [ 0.592, 1.02, 0.652, 1.004, 0.592, 0.989, 0.644, 0.996 ] + }, + { "time": 0.6667 } + ] + }, + "gun": { + "rotate": [ + { + "value": 12.36, + "curve": [ 0.022, 16.28, 0.087, 20.25 ] + }, + { + "time": 0.1333, + "value": 20.19, + "curve": [ 0.168, 20.32, 0.254, -8.82 ] + }, + { + "time": 0.2667, + "value": -11.88, + "curve": [ 0.291, -17.91, 0.344, -24.11 ] + }, + { + "time": 0.4, + "value": -23.88, + "curve": [ 0.448, -23.69, 0.533, -15.47 ] + }, + { "time": 0.5667, "value": -8.69 }, + { "time": 0.6667, "value": 12.36 } + ] + }, + "hip": { + "rotate": [ + { "value": -8.24 } + ], + "translate": [ + { + "x": -3.6, + "y": -34.1, + "curve": [ 0.042, -3.84, 0.118, 7.62, 0.042, -33.74, 0.112, 20.55 ] + }, + { + "time": 0.1667, + "x": 7.61, + "y": 20.36, + "curve": [ 0.194, 7.6, 0.21, 5.06, 0.204, 20.65, 0.217, -8.69 ] + }, + { + "time": 0.2333, + "x": 1.68, + "y": -18.48, + "curve": [ 0.279, -4.99, 0.297, -5.64, 0.254, -31.08, 0.292, -34.55 ] + }, + { + "time": 0.3333, + "x": -5.76, + "y": -35, + "curve": [ 0.379, -5.9, 0.451, 6.8, 0.384, -35.56, 0.428, 17.6 ] + }, + { + "time": 0.5, + "x": 6.61, + "y": 17.01, + "curve": [ 0.536, 6.47, 0.545, 3.56, 0.533, 16.75, 0.548, -8.71 ] + }, + { + "time": 0.5667, + "x": 0.35, + "y": -18.81, + "curve": [ 0.597, -4.07, 0.642, -3.45, 0.584, -28.58, 0.642, -34.32 ] + }, + { "time": 0.6667, "x": -3.6, "y": -34.1 } + ] + }, + "front-foot-target": { + "rotate": [ + { + "value": -62.54, + "curve": [ 0.015, -74.19, 0.056, -103.19 ] + }, + { + "time": 0.0667, + "value": -111.08, + "curve": [ 0.092, -129.44, 0.189, -146.55 ] + }, + { + "time": 0.2333, + "value": -146.32, + "curve": [ 0.285, -146.06, 0.32, -125.1 ] + }, + { "time": 0.3333, "value": -117.24 }, + { + "time": 0.5, + "value": -35.07, + "curve": [ 0.522, -28.64, 0.546, -24.84 ] + }, + { + "time": 0.5667, + "value": -24.9, + "curve": [ 0.595, -25, 0.623, -40.82 ] + }, + { "time": 0.6667, "value": -62.54 } + ], + "translate": [ + { "x": 16.34, "y": 0.18 }, + { + "time": 0.0667, + "x": -101.43, + "y": 8.04, + "curve": [ 0.085, -131.35, 0.129, -207.69, 0.08, 14.9, 0.124, 113.28 ] + }, + { + "time": 0.1667, + "x": -207.92, + "y": 145.81, + "curve": [ 0.196, -208.13, 0.21, -202.91, 0.186, 160.26, 0.206, 163.48 ] + }, + { + "time": 0.2333, + "x": -189.94, + "y": 163.85, + "curve": [ 0.27, -169.94, 0.31, -126.19, 0.269, 164.35, 0.316, 85.97 ] + }, + { + "time": 0.3333, + "x": -90.56, + "y": 78.57, + "curve": [ 0.355, -57.99, 0.376, -29.14, 0.35, 71.55, 0.376, 66.4 ] + }, + { + "time": 0.4, + "x": 2.87, + "y": 66.38, + "curve": [ 0.412, 19.24, 0.469, 90.73, 0.429, 66.37, 0.469, 70.66 ] + }, + { + "time": 0.5, + "x": 117.18, + "y": 70.46, + "curve": [ 0.522, 136.24, 0.542, 151.33, 0.539, 70.2, 0.555, 38.25 ] + }, + { + "time": 0.5667, + "x": 151.49, + "y": 25.29, + "curve": [ 0.578, 146.76, 0.586, 133.13, 0.572, 19.7, 0.582, 12.23 ] + }, + { "time": 0.6, "x": 115.02, "y": 0.1 }, + { "time": 0.6667, "x": 16.34, "y": 0.18 } + ] + }, + "front-leg-target": { + "translate": [ + { "x": -13.95, "y": -30.34 } + ] + }, + "rear-foot-target": { + "rotate": [ + { "value": 18.55 }, + { + "time": 0.2333, + "value": 167.84, + "curve": [ 0.246, 153.66, 0.256, 129.74 ] + }, + { + "time": 0.2667, + "value": 124.32, + "curve": [ 0.296, 124.43, 0.313, 129.93 ] + }, + { + "time": 0.3667, + "value": 129.87, + "curve": [ 0.421, 128.32, 0.519, 0.98 ] + }, + { + "time": 0.5667, + "curve": [ 0.6, 0.27, 0.642, 4.73 ] + }, + { "time": 0.6667, "value": 18.55 } + ], + "translate": [ + { + "x": -176.39, + "y": 134.12, + "curve": [ 0.018, -142.26, 0.054, -94.41, 0.01, 120.96, 0.044, 84.08 ] + }, + { + "time": 0.0667, + "x": -73.56, + "y": 76.68, + "curve": [ 0.086, -42.82, 0.194, 101.2, 0.098, 66.73, 0.198, 60.88 ] + }, + { "time": 0.2333, "x": 98.32, "y": 32.17 }, + { "time": 0.2667, "x": 49.13, "y": -0.63 }, + { + "time": 0.4, + "x": -147.9, + "y": 0.32, + "curve": [ 0.414, -168.78, 0.478, -284.76, 0.43, 30.09, 0.478, 129.14 ] + }, + { + "time": 0.5, + "x": -283.37, + "y": 167.12, + "curve": [ 0.526, -285.66, 0.548, -280.54, 0.516, 194.84, 0.55, 216.53 ] + }, + { + "time": 0.5667, + "x": -266.98, + "y": 216.12, + "curve": [ 0.581, -256.27, 0.643, -206.54, 0.61, 214.82, 0.65, 145.33 ] + }, + { "time": 0.6667, "x": -176.39, "y": 134.12 } + ] + }, + "rear-leg-target": { + "translate": [ + { "x": 85, "y": -33.59 } + ] + }, + "back-foot-tip": { + "rotate": [ + { + "value": -147.04, + "curve": [ 0.033, -113.4, 0.161, 44.34 ] + }, + { + "time": 0.2333, + "value": 43.48, + "curve": [ 0.24, 43.41, 0.282, 35.72 ] + }, + { + "time": 0.3, + "value": 0.29, + "curve": [ 0.347, 0.28, 0.396, 4.27 ] + }, + { + "time": 0.4, + "curve": [ 0.424, -23.8, 0.525, -181.39 ] + }, + { + "time": 0.5667, + "value": -181.39, + "curve": [ 0.592, -181.39, 0.642, -169.09 ] + }, + { "time": 0.6667, "value": -147.04 } + ] + }, + "front-foot-tip": { + "rotate": [ + { + "value": -0.25, + "curve": [ 0.008, -0.25, 0.056, 1.73 ] + }, + { + "time": 0.0667, + "value": -7.68, + "curve": [ 0.075, -43.13, 0.15, -130.44 ] + }, + { + "time": 0.2, + "value": -130.08, + "curve": [ 0.239, -129.79, 0.272, -126.8 ] + }, + { + "time": 0.3, + "value": -116.24, + "curve": [ 0.333, -103.91, 0.348, -86.1 ] + }, + { + "time": 0.3667, + "value": -71.08, + "curve": [ 0.386, -55.25, 0.415, -32.44 ] + }, + { + "time": 0.4333, + "value": -21.63, + "curve": [ 0.47, -0.01, 0.542, 33.42 ] + }, + { + "time": 0.5667, + "value": 33.2, + "curve": [ 0.622, 32.7, 0.569, 0.64 ] + }, + { "time": 0.6667, "value": -0.25 } + ] + }, + "hair1": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0.087, -6.81, 0.143, -5.75 ] + }, + { + "time": 0.1667, + "value": -4.3, + "curve": [ 0.183, -3.28, 0.209, 2.79 ] + }, + { + "time": 0.2333, + "value": 2.78, + "curve": [ 0.262, 2.77, 0.305, -6.63 ] + }, + { + "time": 0.3333, + "value": -6.64, + "curve": [ 0.419, -6.68, 0.49, -4.84 ] + }, + { + "time": 0.5, + "value": -4.38, + "curve": [ 0.518, -3.56, 0.574, 2.32 ] + }, + { + "time": 0.6, + "value": 2.33, + "curve": [ 0.643, 2.35, 0.633, -6.81 ] + }, + { "time": 0.6667, "value": -6.81 } + ] + }, + "hair2": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0.014, -3.17, 0.109, 43.93 ] + }, + { + "time": 0.1333, + "value": 43.95, + "curve": [ 0.177, 43.97, 0.192, -13.76 ] + }, + { + "time": 0.2667, + "value": -13.83, + "curve": [ 0.302, -13.72, 0.322, -8.86 ] + }, + { + "time": 0.3333, + "value": -6.6, + "curve": [ 0.349, -3.5, 0.436, 41.1 ] + }, + { + "time": 0.4667, + "value": 41.05, + "curve": [ 0.51, 40.99, 0.549, -14.06 ] + }, + { + "time": 0.6, + "value": -14.18, + "curve": [ 0.63, -14.26, 0.656, -9.04 ] + }, + { "time": 0.6667, "value": -6.81 } + ] + }, + "hair3": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0.079, -6.83, 0.108, 0.3 ] + }, + { + "time": 0.1333, + "value": 1.96, + "curve": [ 0.177, 4.89, 0.208, 6.28 ] + }, + { + "time": 0.2333, + "value": 6.29, + "curve": [ 0.313, 6.31, 0.383, 3.49 ] + }, + { + "time": 0.4, + "value": 2.58, + "curve": [ 0.442, 0.28, 0.523, -6.81 ] + }, + { "time": 0.6, "value": -6.81 } + ] + }, + "hair4": { + "rotate": [ + { + "value": -6.81, + "curve": [ 0.011, -4.06, 0.108, 24.92 ] + }, + { + "time": 0.1333, + "value": 24.92, + "curve": [ 0.158, 24.92, 0.208, -10.62 ] + }, + { + "time": 0.2333, + "value": -10.62, + "curve": [ 0.254, -10.62, 0.312, -9.73 ] + }, + { + "time": 0.3333, + "value": -6.4, + "curve": [ 0.356, -2.95, 0.438, 24.93 ] + }, + { + "time": 0.4667, + "value": 24.93, + "curve": [ 0.492, 24.93, 0.575, -9.78 ] + }, + { + "time": 0.6, + "value": -9.78, + "curve": [ 0.617, -9.78, 0.655, -8.63 ] + }, + { "time": 0.6667, "value": -6.81 } + ] + }, + "torso2": { + "rotate": [ + { + "value": 3.5, + "curve": [ 0.07, 3.51, 0.075, 8.69 ] + }, + { + "time": 0.1, + "value": 8.69, + "curve": [ 0.139, 8.69, 0.214, 6.9 ] + }, + { + "time": 0.2333, + "value": 6.33, + "curve": [ 0.266, 5.34, 0.285, 3.48 ] + }, + { + "time": 0.3333, + "value": 3.48, + "curve": [ 0.398, 3.48, 0.408, 8.68 ] + }, + { + "time": 0.4333, + "value": 8.68, + "curve": [ 0.458, 8.68, 0.551, 6.8 ] + }, + { + "time": 0.5667, + "value": 6.26, + "curve": [ 0.598, 5.17, 0.642, 3.49 ] + }, + { "time": 0.6667, "value": 3.5 } + ] + }, + "torso3": { + "rotate": [ + { + "value": 4.52, + "curve": [ 0.067, 4.54, 0.075, -7.27 ] + }, + { + "time": 0.1, + "value": -7.27, + "curve": [ 0.125, -7.27, 0.227, 0.84 ] + }, + { + "time": 0.2333, + "value": 1.24, + "curve": [ 0.254, 2.5, 0.301, 4.51 ] + }, + { + "time": 0.3333, + "value": 4.52, + "curve": [ 0.386, 4.54, 0.408, -7.35 ] + }, + { + "time": 0.4333, + "value": -7.35, + "curve": [ 0.458, -7.35, 0.549, -0.14 ] + }, + { + "time": 0.5667, + "value": 0.95, + "curve": [ 0.586, 2.18, 0.632, 4.54 ] + }, + { "time": 0.6667, "value": 4.52 } + ] + }, + "aim-constraint-target": { + "rotate": [ + { "value": 30.57 } + ] + }, + "rear-foot": { + "rotate": [ + { "value": -6.5 } + ] + }, + "front-foot": { + "rotate": [ + { "value": 4.5 } + ] + }, + "head-control": { + "translate": [ + { + "y": -9.94, + "curve": [ 0.058, 0, 0.175, -15.32, 0.044, -4.19, 0.175, 5 ] + }, + { + "time": 0.2333, + "x": -15.32, + "y": 5, + "curve": [ 0.317, -15.32, 0.429, -9.74, 0.317, 5, 0.382, -31.71 ] + }, + { + "time": 0.4667, + "x": -7.81, + "y": -31.59, + "curve": [ 0.507, -5.76, 0.617, 0, 0.549, -31.47, 0.628, -13.33 ] + }, + { "time": 0.6667, "y": -9.94 } + ] + }, + "front-shoulder": { + "translate": [ + { + "x": -0.74, + "y": 11.22, + "curve": [ 0.061, -0.74, 0.144, 1.17, 0.061, 11.22, 0.143, -17.93 ] + }, + { + "time": 0.2333, + "x": 1.19, + "y": -17.9, + "curve": [ 0.54, 1.25, 0.558, -0.74, 0.545, -17.8, 0.558, 11.22 ] + }, + { "time": 0.6667, "x": -0.74, "y": 11.22 } + ] + }, + "back-shoulder": { + "translate": [ + { + "curve": [ 0.083, 0, 0.25, 0, 0.083, 0, 0.25, 8.93 ] + }, + { + "time": 0.3333, + "y": 8.93, + "curve": [ 0.417, 0, 0.583, 0, 0.417, 8.93, 0.583, 0 ] + }, + { "time": 0.6667 } + ] + } + }, + "ik": { + "front-leg-ik": [ + { "softness": 10, "bendPositive": false }, + { "time": 0.5667, "softness": 14.8, "bendPositive": false }, + { "time": 0.6, "softness": 48.2, "bendPositive": false }, + { "time": 0.6667, "softness": 10, "bendPositive": false } + ], + "rear-leg-ik": [ + { "bendPositive": false }, + { "time": 0.1667, "softness": 22.5, "bendPositive": false }, + { "time": 0.3, "softness": 61.4, "bendPositive": false }, + { "time": 0.6667, "bendPositive": false } + ] + }, + "events": [ + { "time": 0.2333, "name": "footstep" }, + { "time": 0.5667, "name": "footstep" } + ] + }, + "run-to-idle": { + "slots": { + "front-fist": { + "attachment": [ + { "name": "front-fist-open" } + ] + } + }, + "bones": { + "front-foot-target": { + "translate": [ + { + "x": -16.5, + "y": 3.41, + "curve": [ 0.033, -16.5, 0.1, -69.06, 0.033, 3.41, 0.1, 0 ] + }, + { "time": 0.1333, "x": -69.06 } + ] + }, + "hip": { + "translate": [ + { + "x": -28.78, + "y": -72.96, + "curve": [ 0.036, -28.63, 0.2, -10.85, 0.135, -62.35, 0.2, -23.15 ] + }, + { "time": 0.2667, "x": -11.97, "y": -23.15 } + ] + }, + "rear-foot-target": { + "translate": [ + { + "x": 33.15, + "y": 31.61, + "curve": [ 0.017, 33.15, 0.05, 24.41, 0.017, 31.61, 0.041, 20.73 ] + }, + { + "time": 0.0667, + "x": 24.41, + "y": 0.19, + "curve": [ 0.117, 24.41, 0.217, 48.87, 0.117, 0.19, 0.217, 0 ] + }, + { "time": 0.2667, "x": 48.87 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -80.61, + "curve": [ 0.067, -80.61, 0.2, -60.87 ] + }, + { "time": 0.2667, "value": -60.87 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 8.79, + "curve": [ 0.041, 8.79, 0.115, 6.3 ] + }, + { + "time": 0.1667, + "value": 6.41, + "curve": [ 0.201, 6.48, 0.241, 42.46 ] + }, + { "time": 0.2667, "value": 42.46 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 55.3, + "curve": [ 0.067, 55.3, 0.2, 39.2 ] + }, + { "time": 0.2667, "value": 39.2 } + ] + }, + "head": { + "rotate": [ + { + "curve": [ 0.05, 0, 0.083, 2.67 ] + }, + { + "time": 0.1333, + "value": 2.67, + "curve": [ 0.15, 2.67, 0.25, -6.75 ] + }, + { "time": 0.2667, "value": -6.75 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": 38.26, + "curve": [ 0.041, 38.26, 0.127, -2.19 ] + }, + { + "time": 0.1667, + "value": -3, + "curve": [ 0.209, -3.84, 0.241, 0 ] + }, + { "time": 0.2667 } + ], + "scale": [ + { + "x": 0.844, + "curve": [ 0.067, 0.844, 0.2, 1, 0.067, 1, 0.2, 1 ] + }, + { "time": 0.2667 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": 57.24, + "curve": [ 0.067, 57.24, 0.2, 0 ] + }, + { "time": 0.2667 } + ] + }, + "gun": { + "rotate": [ + { + "value": 2.28, + "curve": [ 0.041, 2.28, 0.105, 15.34 ] + }, + { + "time": 0.1667, + "value": 15.32, + "curve": [ 0.205, 15.31, 0.241, 0 ] + }, + { "time": 0.2667 } + ] + }, + "torso": { + "rotate": [ + { + "value": -12.98, + "curve": [ 0.033, -12.98, 0.103, -14.81 ] + }, + { + "time": 0.1333, + "value": -16.63, + "curve": [ 0.168, -18.69, 0.233, -22.88 ] + }, + { "time": 0.2667, "value": -22.88 } + ], + "scale": [ + { + "x": 0.963, + "y": 1.074, + "curve": [ 0.067, 0.963, 0.132, 1, 0.067, 1.074, 0.132, 1 ] + }, + { "time": 0.2667 } + ] + }, + "neck": { + "rotate": [ + {}, + { "time": 0.2667, "value": 3.78 } + ] + }, + "hair3": { + "rotate": [ + { + "curve": [ 0.033, 0, 0.1, 0.88 ] + }, + { + "time": 0.1333, + "value": 0.88, + "curve": [ 0.167, 0.88, 0.233, 0 ] + }, + { "time": 0.2667 } + ] + }, + "hair4": { + "rotate": [ + { + "curve": [ 0.033, 0, 0.1, 15.97 ] + }, + { + "time": 0.1333, + "value": 15.97, + "curve": [ 0.167, 15.97, 0.233, 0 ] + }, + { "time": 0.2667 } + ] + }, + "hair1": { + "rotate": [ + { + "curve": [ 0.033, 0, 0.1, 10.76 ] + }, + { + "time": 0.1333, + "value": 10.76, + "curve": [ 0.167, 10.76, 0.233, 0 ] + }, + { "time": 0.2667 } + ] + }, + "hair2": { + "rotate": [ + { + "curve": [ 0.014, -2.28, 0.042, -7.84 ] + }, + { + "time": 0.0667, + "value": -7.82, + "curve": [ 0.108, -7.79, 0.166, 6.57 ] + }, + { + "time": 0.2, + "value": 6.67, + "curve": [ 0.222, 6.73, 0.255, 1.98 ] + }, + { "time": 0.2667 } + ] + }, + "torso2": { + "rotate": [ + { + "curve": [ 0.041, 0, 0.107, 3.03 ] + }, + { + "time": 0.1667, + "value": 3.03, + "curve": [ 0.205, 3.03, 0.241, 0 ] + }, + { "time": 0.2667 } + ] + }, + "torso3": { + "rotate": [ + { + "curve": [ 0.049, 0, 0.166, 0.66 ] + }, + { + "time": 0.2, + "value": 0.66, + "curve": [ 0.232, 0.65, 0.249, -2.15 ] + }, + { "time": 0.2667, "value": -2.15 } + ] + }, + "head-control": { + "translate": [ + { "x": -10.12, "y": 8.71 }, + { "time": 0.2667 } + ] + }, + "front-shoulder": { + "translate": [ + { "x": 4.91, "y": 11.54 }, + { "time": 0.2667 } + ] + } + } + }, + "shoot": { + "slots": { + "muzzle": { + "rgba": [ + { "time": 0.1333, "color": "ffffffff" }, + { "time": 0.2, "color": "ffffff62" } + ], + "attachment": [ + { "time": 0.0333, "name": "muzzle01" }, + { "time": 0.0667, "name": "muzzle02" }, + { "time": 0.1, "name": "muzzle03" }, + { "time": 0.1333, "name": "muzzle04" }, + { "time": 0.1667, "name": "muzzle05" }, + { "time": 0.2 } + ] + }, + "muzzle-glow": { + "rgba": [ + { "color": "ff0c0c00" }, + { + "time": 0.0333, + "color": "ffc9adff", + "curve": [ 0.255, 1, 0.273, 1, 0.255, 0.76, 0.273, 0.4, 0.255, 0.65, 0.273, 0.22, 0.255, 1, 0.273, 1 ] + }, + { "time": 0.3, "color": "ff400cff" }, + { "time": 0.6333, "color": "ff0c0c00" } + ], + "attachment": [ + { "name": "muzzle-glow" } + ] + }, + "muzzle-ring": { + "rgba": [ + { + "time": 0.0333, + "color": "d8baffff", + "curve": [ 0.202, 0.85, 0.214, 0.84, 0.202, 0.73, 0.214, 0.73, 0.202, 1, 0.214, 1, 0.202, 1, 0.214, 0.21 ] + }, + { "time": 0.2333, "color": "d7baff00" } + ], + "attachment": [ + { "time": 0.0333, "name": "muzzle-ring" }, + { "time": 0.2333 } + ] + }, + "muzzle-ring2": { + "rgba": [ + { + "time": 0.0333, + "color": "d8baffff", + "curve": [ 0.174, 0.85, 0.184, 0.84, 0.174, 0.73, 0.184, 0.73, 0.174, 1, 0.184, 1, 0.174, 1, 0.184, 0.21 ] + }, + { "time": 0.2, "color": "d7baff00" } + ], + "attachment": [ + { "time": 0.0333, "name": "muzzle-ring" }, + { "time": 0.2 } + ] + }, + "muzzle-ring3": { + "rgba": [ + { + "time": 0.0333, + "color": "d8baffff", + "curve": [ 0.174, 0.85, 0.184, 0.84, 0.174, 0.73, 0.184, 0.73, 0.174, 1, 0.184, 1, 0.174, 1, 0.184, 0.21 ] + }, + { "time": 0.2, "color": "d7baff00" } + ], + "attachment": [ + { "time": 0.0333, "name": "muzzle-ring" }, + { "time": 0.2 } + ] + }, + "muzzle-ring4": { + "rgba": [ + { + "time": 0.0333, + "color": "d8baffff", + "curve": [ 0.174, 0.85, 0.184, 0.84, 0.174, 0.73, 0.184, 0.73, 0.174, 1, 0.184, 1, 0.174, 1, 0.184, 0.21 ] + }, + { "time": 0.2, "color": "d7baff00" } + ], + "attachment": [ + { "time": 0.0333, "name": "muzzle-ring" }, + { "time": 0.2 } + ] + } + }, + "bones": { + "gun": { + "rotate": [ + { + "time": 0.0667, + "curve": [ 0.094, 25.89, 0.112, 45.27 ] + }, + { + "time": 0.1333, + "value": 45.35, + "curve": [ 0.192, 45.28, 0.18, -0.09 ] + }, + { "time": 0.6333 } + ] + }, + "muzzle": { + "translate": [ + { "x": -11.02, "y": 25.16 } + ] + }, + "rear-upper-arm": { + "translate": [ + { + "time": 0.0333, + "curve": [ 0.045, 0.91, 0.083, 3.46, 0.044, 0.86, 0.083, 3.32 ] + }, + { + "time": 0.1, + "x": 3.46, + "y": 3.32, + "curve": [ 0.133, 3.46, 0.176, -0.1, 0.133, 3.32, 0.169, 0 ] + }, + { "time": 0.2333 } + ] + }, + "rear-bracer": { + "translate": [ + { + "time": 0.0333, + "curve": [ 0.075, -3.78, 0.083, -4.36, 0.08, -2.7, 0.083, -2.88 ] + }, + { + "time": 0.1, + "x": -4.36, + "y": -2.88, + "curve": [ 0.133, -4.36, 0.168, 0.18, 0.133, -2.88, 0.167, 0 ] + }, + { "time": 0.2333 } + ] + }, + "gun-tip": { + "translate": [ + {}, + { "time": 0.3, "x": 3.15, "y": 0.39 } + ], + "scale": [ + { "x": 0.366, "y": 0.366 }, + { "time": 0.0333, "x": 1.453, "y": 1.453 }, + { "time": 0.3, "x": 0.366, "y": 0.366 } + ] + }, + "muzzle-ring": { + "translate": [ + { "time": 0.0333 }, + { "time": 0.2333, "x": 64.47 } + ], + "scale": [ + { "time": 0.0333 }, + { "time": 0.2333, "x": 5.951, "y": 5.951 } + ] + }, + "muzzle-ring2": { + "translate": [ + { "time": 0.0333 }, + { "time": 0.2, "x": 172.57 } + ], + "scale": [ + { "time": 0.0333 }, + { "time": 0.2, "x": 4, "y": 4 } + ] + }, + "muzzle-ring3": { + "translate": [ + { "time": 0.0333 }, + { "time": 0.2, "x": 277.17 } + ], + "scale": [ + { "time": 0.0333 }, + { "time": 0.2, "x": 2, "y": 2 } + ] + }, + "muzzle-ring4": { + "translate": [ + { "time": 0.0333 }, + { "time": 0.2, "x": 392.06 } + ] + } + } + }, + "walk": { + "bones": { + "rear-foot-target": { + "rotate": [ + { + "value": -32.82, + "curve": [ 0.035, -42.69, 0.057, -70.49 ] + }, + { + "time": 0.1, + "value": -70.59, + "curve": [ 0.236, -70.78, 0.335, -9.87 ] + }, + { + "time": 0.3667, + "value": -1.56, + "curve": [ 0.393, 5.5, 0.477, 13.96 ] + }, + { + "time": 0.5, + "value": 13.96, + "curve": [ 0.519, 13.96, 0.508, 0.13 ] + }, + { "time": 0.5667, "value": -0.28 }, + { + "time": 0.7333, + "value": -0.28, + "curve": [ 0.827, -0.06, 0.958, -21.07 ] + }, + { "time": 1, "value": -32.82 } + ], + "translate": [ + { + "x": -167.32, + "y": 0.58, + "curve": [ 0.022, -180.55, 0.075, -235.51, 0.045, 0.58, 0.075, 30.12 ] + }, + { + "time": 0.1, + "x": -235.51, + "y": 39.92, + "curve": [ 0.142, -235.51, 0.208, -201.73, 0.138, 54.94, 0.18, 60.78 ] + }, + { + "time": 0.2333, + "x": -176.33, + "y": 61.48, + "curve": [ 0.272, -136.61, 0.321, -45.18, 0.275, 62.02, 0.321, 56.6 ] + }, + { + "time": 0.3667, + "x": 8.44, + "y": 49.67, + "curve": [ 0.403, 51.03, 0.486, 66.86, 0.401, 44.37, 0.48, 23.11 ] + }, + { "time": 0.5, "x": 66.57, "y": 14.22 }, + { "time": 0.5333, "x": 52.58, "y": 0.6 }, + { "time": 1, "x": -167.32, "y": 0.58 } + ] + }, + "front-foot-target": { + "rotate": [ + { + "value": 18.19, + "curve": [ 0.01, 11.17, 0.043, 1.37 ] + }, + { "time": 0.1, "value": 0.47 }, + { + "time": 0.2333, + "value": 0.55, + "curve": [ 0.364, 0.3, 0.515, -80.48 ] + }, + { + "time": 0.7333, + "value": -80.78, + "curve": [ 0.788, -80.38, 0.921, 17.42 ] + }, + { "time": 1, "value": 18.19 } + ], + "translate": [ + { + "x": 139.21, + "y": 22.94, + "curve": [ 0.025, 139.21, 0.069, 111.46, 0.031, 3.25, 0.075, 0.06 ] + }, + { "time": 0.1, "x": 96.69, "y": 0.06 }, + { + "time": 0.5, + "x": -94.87, + "y": -0.03, + "curve": [ 0.518, -106.82, 0.575, -152.56, 0.534, 5.42, 0.557, 38.46 ] + }, + { + "time": 0.6, + "x": -152.56, + "y": 57.05, + "curve": [ 0.633, -152.56, 0.688, -128.05, 0.643, 75.61, 0.7, 84.14 ] + }, + { + "time": 0.7333, + "x": -109.42, + "y": 84.14, + "curve": [ 0.771, -93.91, 0.832, -30.64, 0.787, 84.14, 0.799, 89.65 ] + }, + { + "time": 0.8667, + "x": 17, + "y": 75.25, + "curve": [ 0.903, 66.18, 0.967, 139.21, 0.932, 61.53, 0.967, 44.02 ] + }, + { "time": 1, "x": 139.21, "y": 22.94 } + ] + }, + "hip": { + "rotate": [ + { "value": -4.35 } + ], + "translate": [ + { + "x": -2.86, + "y": -13.86, + "curve": [ 0.025, -2.84, 0.067, -2.82, 0.028, -19.14, 0.054, -24.02 ] + }, + { + "time": 0.1, + "x": -2.61, + "y": -24.19, + "curve": [ 0.143, -2.34, 0.202, -1.79, 0.152, -23.98, 0.213, -14.81 ] + }, + { + "time": 0.2667, + "x": -1.21, + "y": -7.12, + "curve": [ 0.308, -0.86, 0.345, -0.51, 0.306, -1.63, 0.341, 3.15 ] + }, + { + "time": 0.3667, + "x": -0.33, + "y": 3.15, + "curve": [ 0.41, 0.02, 0.458, 0.26, 0.427, 3.3, 0.481, -6.75 ] + }, + { + "time": 0.5, + "x": 0.26, + "y": -10.59, + "curve": [ 0.553, 0.26, 0.559, 0.2, 0.519, -14.41, 0.548, -23.88 ] + }, + { + "time": 0.6, + "x": -0.17, + "y": -23.71, + "curve": [ 0.663, -0.72, 0.798, -2.09, 0.702, -23.36, 0.802, 3.53 ] + }, + { + "time": 0.8667, + "x": -2.46, + "y": 3.48, + "curve": [ 0.901, -2.63, 0.967, -2.87, 0.913, 3.45, 0.967, -7.64 ] + }, + { "time": 1, "x": -2.86, "y": -13.86 } + ] + }, + "front-foot-tip": { + "rotate": [ + { + "value": 28.96, + "curve": [ 0.056, 28.74, 0.049, 19.6 ] + }, + { "time": 0.0667, "value": 1.68 }, + { + "time": 0.5, + "value": -10, + "curve": [ 0.525, -10, 0.592, -54.69 ] + }, + { + "time": 0.6, + "value": -59.66, + "curve": [ 0.623, -74.54, 0.674, -101.78 ] + }, + { + "time": 0.7333, + "value": -101.78, + "curve": [ 0.812, -101.78, 0.855, -84.67 ] + }, + { + "time": 0.8667, + "value": -63.53, + "curve": [ 0.869, -58.38, 0.975, 28.96 ] + }, + { "time": 1, "value": 28.96 } + ] + }, + "torso": { + "rotate": [ + { + "value": -20.72, + "curve": [ 0.025, -20.57, 0.071, -20.04 ] + }, + { + "time": 0.1333, + "value": -20.04, + "curve": [ 0.187, -20.04, 0.285, -21.16 ] + }, + { + "time": 0.3667, + "value": -21.16, + "curve": [ 0.405, -21.16, 0.47, -20.9 ] + }, + { + "time": 0.5, + "value": -20.71, + "curve": [ 0.518, -20.6, 0.582, -20.03 ] + }, + { + "time": 0.6333, + "value": -20.04, + "curve": [ 0.709, -20.05, 0.815, -21.18 ] + }, + { + "time": 0.8667, + "value": -21.18, + "curve": [ 0.908, -21.18, 0.971, -20.93 ] + }, + { "time": 1, "value": -20.72 } + ] + }, + "neck": { + "rotate": [ + { + "value": 17.78, + "curve": [ 0.025, 17.93, 0.071, 18.46 ] + }, + { + "time": 0.1333, + "value": 18.46, + "curve": [ 0.187, 18.46, 0.285, 17.34 ] + }, + { + "time": 0.3667, + "value": 17.34, + "curve": [ 0.405, 17.34, 0.47, 17.6 ] + }, + { + "time": 0.5, + "value": 17.79, + "curve": [ 0.518, 17.9, 0.582, 18.47 ] + }, + { + "time": 0.6333, + "value": 18.46, + "curve": [ 0.709, 18.45, 0.815, 17.32 ] + }, + { + "time": 0.8667, + "value": 17.32, + "curve": [ 0.908, 17.32, 0.971, 17.57 ] + }, + { "time": 1, "value": 17.78 } + ] + }, + "head": { + "rotate": [ + { + "value": -12.23, + "curve": [ 0.061, -12.23, 0.191, -7.45 ] + }, + { + "time": 0.2667, + "value": -7.43, + "curve": [ 0.341, -7.42, 0.421, -12.23 ] + }, + { + "time": 0.5, + "value": -12.23, + "curve": [ 0.567, -12.26, 0.694, -7.46 ] + }, + { + "time": 0.7667, + "value": -7.47, + "curve": [ 0.853, -7.49, 0.943, -12.23 ] + }, + { "time": 1, "value": -12.23 } + ], + "scale": [ + { + "curve": [ 0.039, 1, 0.084, 0.991, 0.039, 1, 0.084, 1.019 ] + }, + { + "time": 0.1333, + "x": 0.991, + "y": 1.019, + "curve": [ 0.205, 0.991, 0.318, 1.019, 0.205, 1.019, 0.337, 0.992 ] + }, + { + "time": 0.4, + "x": 1.019, + "y": 0.992, + "curve": [ 0.456, 1.019, 0.494, 1.001, 0.483, 0.991, 0.493, 0.999 ] + }, + { + "time": 0.5, + "curve": [ 0.508, 0.998, 0.584, 0.991, 0.51, 1.002, 0.584, 1.019 ] + }, + { + "time": 0.6333, + "x": 0.991, + "y": 1.019, + "curve": [ 0.705, 0.991, 0.818, 1.019, 0.705, 1.019, 0.837, 0.992 ] + }, + { + "time": 0.9, + "x": 1.019, + "y": 0.992, + "curve": [ 0.956, 1.019, 0.955, 1, 0.983, 0.991, 0.955, 1 ] + }, + { "time": 1 } + ] + }, + "back-foot-tip": { + "rotate": [ + { "value": 4.09 }, + { "time": 0.0333, "value": 3.05 }, + { + "time": 0.1, + "value": -59.01, + "curve": [ 0.124, -72.97, 0.169, -100.05 ] + }, + { + "time": 0.2333, + "value": -99.71, + "curve": [ 0.326, -99.21, 0.349, -37.4 ] + }, + { + "time": 0.3667, + "value": -17.85, + "curve": [ 0.388, 4.74, 0.451, 32.35 ] + }, + { + "time": 0.5, + "value": 32.4, + "curve": [ 0.537, 32.44, 0.566, 6.43 ] + }, + { "time": 0.5667, "value": 2 }, + { "time": 1, "value": 4.09 } + ] + }, + "front-thigh": { + "translate": [ + { + "x": 17.15, + "y": -0.09, + "curve": [ 0.178, 17.14, 0.295, -4.26, 0.009, -0.09, 0.475, 0.02 ] + }, + { + "time": 0.5, + "x": -4.26, + "y": 0.02, + "curve": [ 0.705, -4.27, 0.848, 17.15, 0.525, 0.02, 0.975, -0.09 ] + }, + { "time": 1, "x": 17.15, "y": -0.09 } + ] + }, + "rear-thigh": { + "translate": [ + { + "x": -17.71, + "y": -4.63, + "curve": [ 0.036, -19.81, 0.043, -20.86, 0.036, -4.63, 0.05, -7.03 ] + }, + { + "time": 0.1, + "x": -20.95, + "y": -7.06, + "curve": [ 0.162, -21.05, 0.4, 7.79, 0.2, -7.13, 0.4, -1.9 ] + }, + { + "time": 0.5, + "x": 7.79, + "y": -1.94, + "curve": [ 0.612, 7.69, 0.875, -10.49, 0.592, -1.97, 0.917, -3.25 ] + }, + { "time": 1, "x": -17.71, "y": -4.63 } + ] + }, + "torso2": { + "rotate": [ + { + "value": 1, + "curve": [ 0.006, 1.2, 0.084, 2.88 ] + }, + { + "time": 0.1333, + "value": 2.88, + "curve": [ 0.205, 2.88, 0.284, -1.17 ] + }, + { + "time": 0.3667, + "value": -1.17, + "curve": [ 0.411, -1.17, 0.481, 0.57 ] + }, + { + "time": 0.5, + "value": 1, + "curve": [ 0.515, 1.33, 0.59, 2.83 ] + }, + { + "time": 0.6333, + "value": 2.85, + "curve": [ 0.683, 2.86, 0.796, -1.2 ] + }, + { + "time": 0.8667, + "value": -1.2, + "curve": [ 0.916, -1.2, 0.984, 0.62 ] + }, + { "time": 1, "value": 1 } + ] + }, + "torso3": { + "rotate": [ + { "value": -1.81 } + ] + }, + "front-upper-arm": { + "rotate": [ + { + "value": -9.51, + "curve": [ 0.021, -13.32, 0.058, -19.4 ] + }, + { + "time": 0.1, + "value": -19.4, + "curve": [ 0.238, -19.69, 0.337, 7.78 ] + }, + { + "time": 0.3667, + "value": 16.2, + "curve": [ 0.399, 25.42, 0.497, 60.19 ] + }, + { + "time": 0.6, + "value": 60.26, + "curve": [ 0.719, 60.13, 0.845, 27.61 ] + }, + { + "time": 0.8667, + "value": 22.45, + "curve": [ 0.892, 16.38, 0.979, -3.27 ] + }, + { "time": 1, "value": -9.51 } + ] + }, + "front-bracer": { + "rotate": [ + { + "value": 13.57, + "curve": [ 0.022, 9.71, 0.147, -3.78 ] + }, + { + "time": 0.3667, + "value": -3.69, + "curve": [ 0.457, -3.66, 0.479, 0.83 ] + }, + { + "time": 0.5, + "value": 4.05, + "curve": [ 0.513, 6.08, 0.635, 30.8 ] + }, + { + "time": 0.8, + "value": 30.92, + "curve": [ 0.974, 31, 0.98, 18.35 ] + }, + { "time": 1, "value": 13.57 } + ] + }, + "front-fist": { + "rotate": [ + { + "value": -28.72, + "curve": [ 0.024, -31.74, 0.176, -43.4 ] + }, + { + "time": 0.3667, + "value": -43.6, + "curve": [ 0.403, -43.65, 0.47, -40.15 ] + }, + { + "time": 0.5, + "value": -35.63, + "curve": [ 0.547, -28.59, 0.624, -4.57 ] + }, + { + "time": 0.7333, + "value": -4.59, + "curve": [ 0.891, -4.62, 0.954, -24.28 ] + }, + { "time": 1, "value": -28.48 } + ] + }, + "rear-upper-arm": { + "rotate": [ + { + "value": 28.28, + "curve": [ 0.034, 30.94, 0.068, 32.05 ] + }, + { + "time": 0.1, + "value": 31.88, + "curve": [ 0.194, 31.01, 0.336, -0.11 ] + }, + { + "time": 0.3667, + "value": -7.11, + "curve": [ 0.421, -19.73, 0.53, -46.21 ] + }, + { + "time": 0.6, + "value": -45.75, + "curve": [ 0.708, -45.03, 0.844, -13.56 ] + }, + { + "time": 0.8667, + "value": -6.48, + "curve": [ 0.909, 6.59, 0.958, 24.21 ] + }, + { "time": 1, "value": 28.28 } + ] + }, + "hair2": { + "rotate": [ + { + "value": -2.79, + "curve": [ 0.074, -2.84, 0.121, 25.08 ] + }, + { + "time": 0.2333, + "value": 24.99, + "curve": [ 0.35, 24.89, 0.427, -2.86 ] + }, + { + "time": 0.5, + "value": -2.8, + "curve": [ 0.575, -2.73, 0.652, 24.5 ] + }, + { + "time": 0.7333, + "value": 24.55, + "curve": [ 0.828, 24.6, 0.932, -2.69 ] + }, + { "time": 1, "value": -2.79 } + ] + }, + "hair4": { + "rotate": [ + { + "value": -6.01, + "curve": [ 0.106, -5.97, 0.151, 18.62 ] + }, + { + "time": 0.2333, + "value": 18.72, + "curve": [ 0.336, 18.7, 0.405, -11.37 ] + }, + { + "time": 0.5, + "value": -11.45, + "curve": [ 0.626, -11.46, 0.629, 18.94 ] + }, + { + "time": 0.7333, + "value": 18.92, + "curve": [ 0.833, 18.92, 0.913, -6.06 ] + }, + { "time": 1, "value": -6.01 } + ], + "translate": [ + { "x": 0.03, "y": 1.35 } + ] + }, + "rear-bracer": { + "rotate": [ + { + "value": 10.06, + "curve": [ 0.044, 11.16, 0.063, 11.49 ] + }, + { + "time": 0.1, + "value": 11.49, + "curve": [ 0.215, 11.49, 0.336, 2.92 ] + }, + { + "time": 0.3667, + "value": 0.84, + "curve": [ 0.416, -2.52, 0.498, -10.84 ] + }, + { + "time": 0.6, + "value": -10.83, + "curve": [ 0.762, -10.71, 0.845, -3.05 ] + }, + { + "time": 0.8667, + "value": -1.34, + "curve": [ 0.917, 2.54, 0.977, 8.81 ] + }, + { "time": 1, "value": 10.06 } + ] + }, + "gun": { + "rotate": [ + { + "value": -14.67, + "curve": [ 0.086, -14.67, 0.202, 8.31 ] + }, + { + "time": 0.2333, + "value": 12.14, + "curve": [ 0.279, 17.71, 0.391, 25.79 ] + }, + { + "time": 0.5, + "value": 25.77, + "curve": [ 0.631, 25.74, 0.694, 4.53 ] + }, + { + "time": 0.7333, + "value": -0.65, + "curve": [ 0.768, -5.21, 0.902, -14.4 ] + }, + { "time": 1, "value": -14.67 } + ] + }, + "front-leg-target": { + "translate": [ + { + "x": -2.83, + "y": -8.48, + "curve": [ 0.008, -2.83, 0.058, 0.09, 0.001, 4.97, 0.058, 6.68 ] + }, + { + "time": 0.0667, + "x": 0.09, + "y": 6.68, + "curve": [ 0.3, 0.09, 0.767, -2.83, 0.3, 6.68, 0.767, -8.48 ] + }, + { "time": 1, "x": -2.83, "y": -8.48 } + ] + }, + "hair1": { + "rotate": [ + { + "curve": [ 0.028, 1.24, 0.016, 3.46 ] + }, + { + "time": 0.1, + "value": 3.45, + "curve": [ 0.159, 3.45, 0.189, 0.23 ] + }, + { + "time": 0.2333, + "value": -2.29, + "curve": [ 0.265, -4.32, 0.305, -5.92 ] + }, + { + "time": 0.3667, + "value": -5.94, + "curve": [ 0.446, -5.96, 0.52, 3.41 ] + }, + { + "time": 0.6, + "value": 3.42, + "curve": [ 0.717, 3.42, 0.772, -5.93 ] + }, + { + "time": 0.8667, + "value": -5.97, + "curve": [ 0.933, -5.99, 0.982, -0.94 ] + }, + { "time": 1 } + ] + }, + "hair3": { + "rotate": [ + { + "curve": [ 0.067, 0, 0.159, -10.48 ] + }, + { + "time": 0.2333, + "value": -10.49, + "curve": [ 0.334, -10.5, 0.439, -0.09 ] + }, + { + "time": 0.5, + "value": -0.09, + "curve": [ 0.569, -0.09, 0.658, -10.75 ] + }, + { + "time": 0.7333, + "value": -10.7, + "curve": [ 0.833, -10.63, 0.947, 0 ] + }, + { "time": 1 } + ] + }, + "gun-tip": { + "rotate": [ + { "time": 0.2333, "value": 0.11 } + ] + }, + "muzzle-ring": { + "rotate": [ + { "time": 0.2333, "value": 0.11 } + ] + }, + "muzzle-ring2": { + "rotate": [ + { "time": 0.2667, "value": 0.11 } + ] + }, + "muzzle-ring3": { + "rotate": [ + { "time": 0.2667, "value": 0.11 } + ] + }, + "muzzle-ring4": { + "rotate": [ + { "time": 0.2667, "value": 0.11 } + ] + }, + "back-shoulder": { + "translate": [ + { + "x": -0.18, + "y": -4.49, + "curve": [ 0.133, -0.18, 0.333, 7.69, 0.133, -4.49, 0.333, 2.77 ] + }, + { + "time": 0.4667, + "x": 7.69, + "y": 2.77, + "curve": [ 0.6, 7.69, 0.858, -0.18, 0.6, 2.77, 0.858, -4.49 ] + }, + { "time": 1, "x": -0.18, "y": -4.49 } + ] + }, + "front-shoulder": { + "translate": [ + { + "x": 1.46, + "y": 9.37, + "curve": [ 0.162, 1.41, 0.333, -1.66, 0.162, 9.37, 0.301, -7.23 ] + }, + { + "time": 0.5, + "x": -1.6, + "y": -7.27, + "curve": [ 0.735, -1.5, 0.847, 1.46, 0.723, -7.31, 0.838, 9.32 ] + }, + { "time": 1, "x": 1.46, "y": 9.37 } + ] + }, + "head-control": { + "translate": [ + { + "x": -6.46, + "y": -8.4, + "curve": [ 0.053, -5.31, 0.167, -3.64, 0.093, -8.4, 0.196, -3.81 ] + }, + { + "time": 0.2333, + "x": -3.64, + "y": -1.32, + "curve": [ 0.309, -3.64, 0.436, -5.84, 0.275, 1.43, 0.38, 10.3 ] + }, + { + "time": 0.5, + "x": -7.03, + "y": 10.29, + "curve": [ 0.538, -7.75, 0.66, -10.54, 0.598, 10.27, 0.694, 1.56 ] + }, + { + "time": 0.7333, + "x": -10.54, + "y": -1.26, + "curve": [ 0.797, -10.54, 0.933, -7.91, 0.768, -3.79, 0.875, -8.4 ] + }, + { "time": 1, "x": -6.46, "y": -8.4 } + ] + } + }, + "ik": { + "front-leg-ik": [ + { + "softness": 25.7, + "bendPositive": false, + "curve": [ 0.008, 1, 0.025, 1, 0.008, 25.7, 0.025, 9.9 ] + }, + { + "time": 0.0333, + "softness": 9.9, + "bendPositive": false, + "curve": [ 0.15, 1, 0.383, 1, 0.15, 9.9, 0.383, 43.2 ] + }, + { + "time": 0.5, + "softness": 43.2, + "bendPositive": false, + "curve": [ 0.625, 1, 0.875, 1, 0.625, 43.2, 0.846, 45.57 ] + }, + { "time": 1, "softness": 25.7, "bendPositive": false } + ], + "rear-leg-ik": [ + { "softness": 5, "bendPositive": false }, + { "time": 0.4333, "softness": 4.9, "bendPositive": false }, + { "time": 0.5, "softness": 28.81, "bendPositive": false }, + { "time": 0.6, "softness": 43.8, "bendPositive": false }, + { "time": 1, "softness": 5, "bendPositive": false } + ] + }, + "events": [ + { "name": "footstep" }, + { "time": 0.5, "name": "footstep" } + ] + } +} +} \ No newline at end of file diff --git a/spine-flutter/example/assets/spineboy-pro.skel b/spine-flutter/example/assets/spineboy-pro.skel new file mode 100644 index 000000000..199839b49 Binary files /dev/null and b/spine-flutter/example/assets/spineboy-pro.skel differ diff --git a/spine-flutter/example/assets/spineboy.atlas b/spine-flutter/example/assets/spineboy.atlas new file mode 100644 index 000000000..b07ccc3bf --- /dev/null +++ b/spine-flutter/example/assets/spineboy.atlas @@ -0,0 +1,101 @@ +spineboy.png + size: 1024, 256 + filter: Linear, Linear + scale: 0.5 +crosshair + bounds: 813, 160, 45, 45 +eye-indifferent + bounds: 569, 2, 47, 45 +eye-surprised + bounds: 643, 7, 47, 45 + rotate: 90 +front-bracer + bounds: 811, 51, 29, 40 +front-fist-closed + bounds: 807, 93, 38, 41 +front-fist-open + bounds: 815, 210, 43, 44 +front-foot + bounds: 706, 64, 63, 35 + rotate: 90 +front-shin + bounds: 80, 11, 41, 92 +front-thigh + bounds: 754, 12, 23, 56 +front-upper-arm + bounds: 618, 5, 23, 49 +goggles + bounds: 214, 20, 131, 83 +gun + bounds: 347, 14, 105, 102 + rotate: 90 +head + bounds: 80, 105, 136, 149 +hoverboard-board + bounds: 2, 8, 246, 76 + rotate: 90 +hoverboard-thruster + bounds: 478, 2, 30, 32 +hoverglow-small + bounds: 218, 117, 137, 38 + rotate: 90 +mouth-grind + bounds: 775, 80, 47, 30 + rotate: 90 +mouth-oooo + bounds: 779, 31, 47, 30 + rotate: 90 +mouth-smile + bounds: 783, 207, 47, 30 + rotate: 90 +muzzle-glow + bounds: 779, 4, 25, 25 +muzzle-ring + bounds: 451, 14, 25, 105 +muzzle01 + bounds: 664, 60, 67, 40 + rotate: 90 +muzzle02 + bounds: 580, 56, 68, 42 + rotate: 90 +muzzle03 + bounds: 478, 36, 83, 53 + rotate: 90 +muzzle04 + bounds: 533, 49, 75, 45 + rotate: 90 +muzzle05 + bounds: 624, 56, 68, 38 + rotate: 90 +neck + bounds: 806, 8, 18, 21 +portal-bg + bounds: 258, 121, 133, 133 +portal-flare1 + bounds: 690, 2, 56, 30 + rotate: 90 +portal-flare2 + bounds: 510, 3, 57, 31 +portal-flare3 + bounds: 722, 4, 58, 30 + rotate: 90 +portal-shade + bounds: 393, 121, 133, 133 +portal-streaks1 + bounds: 528, 126, 126, 128 +portal-streaks2 + bounds: 656, 129, 125, 125 +rear-bracer + bounds: 826, 13, 28, 36 +rear-foot + bounds: 743, 70, 57, 30 + rotate: 90 +rear-shin + bounds: 174, 14, 38, 89 +rear-thigh + bounds: 783, 158, 28, 47 +rear-upper-arm + bounds: 783, 136, 20, 44 + rotate: 90 +torso + bounds: 123, 13, 49, 90 diff --git a/spine-flutter/example/assets/spineboy.png b/spine-flutter/example/assets/spineboy.png new file mode 100644 index 000000000..d1c3ac1be Binary files /dev/null and b/spine-flutter/example/assets/spineboy.png differ diff --git a/spine-flutter/example/ios/.gitignore b/spine-flutter/example/ios/.gitignore new file mode 100644 index 000000000..7a7f9873a --- /dev/null +++ b/spine-flutter/example/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/spine-flutter/example/ios/Flutter/AppFrameworkInfo.plist b/spine-flutter/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000..9625e105d --- /dev/null +++ b/spine-flutter/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 11.0 + + diff --git a/spine-flutter/example/ios/Flutter/Debug.xcconfig b/spine-flutter/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..ec97fc6f3 --- /dev/null +++ b/spine-flutter/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/spine-flutter/example/ios/Flutter/Release.xcconfig b/spine-flutter/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..c4855bfe2 --- /dev/null +++ b/spine-flutter/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/spine-flutter/example/ios/Podfile b/spine-flutter/example/ios/Podfile new file mode 100644 index 000000000..88359b225 --- /dev/null +++ b/spine-flutter/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/spine-flutter/example/ios/Podfile.lock b/spine-flutter/example/ios/Podfile.lock new file mode 100644 index 000000000..552d24f2f --- /dev/null +++ b/spine-flutter/example/ios/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - Flutter (1.0.0) + - spine_flutter (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - spine_flutter (from `.symlinks/plugins/spine_flutter/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + spine_flutter: + :path: ".symlinks/plugins/spine_flutter/ios" + +SPEC CHECKSUMS: + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + spine_flutter: 25063c3b7039f2fc0986b260b801a8bbc8906a3f + +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 + +COCOAPODS: 1.11.3 diff --git a/spine-flutter/example/ios/Runner.xcodeproj/project.pbxproj b/spine-flutter/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..034aaeae5 --- /dev/null +++ b/spine-flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,551 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 777D8D112000B6AC703D6124 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE47748514E81CED33B6EDD5 /* Pods_Runner.framework */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0A0ED2F7954A1E765F7844E6 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 21C14CF0973DAFF83E6DB0B0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3F7F5074FAFBCDFAE6EF8D07 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BE47748514E81CED33B6EDD5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 777D8D112000B6AC703D6124 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8B9D75E8C5E0009A3BF2A9E6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BE47748514E81CED33B6EDD5 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + AFB2390791D3B8AA864ACD02 /* Pods */, + 8B9D75E8C5E0009A3BF2A9E6 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + AFB2390791D3B8AA864ACD02 /* Pods */ = { + isa = PBXGroup; + children = ( + 21C14CF0973DAFF83E6DB0B0 /* Pods-Runner.debug.xcconfig */, + 3F7F5074FAFBCDFAE6EF8D07 /* Pods-Runner.release.xcconfig */, + 0A0ED2F7954A1E765F7844E6 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + B3F9EFA5320DF0D4B11CC671 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 8436C011D9463CCA25592170 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 8436C011D9463CCA25592170 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + B3F9EFA5320DF0D4B11CC671 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/spine-flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/spine-flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/spine-flutter/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/spine-flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/spine-flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..21a3cc14c --- /dev/null +++ b/spine-flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/spine-flutter/example/ios/Runner/AppDelegate.swift b/spine-flutter/example/ios/Runner/AppDelegate.swift new file mode 100644 index 000000000..70693e4a8 --- /dev/null +++ b/spine-flutter/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d36b1fab2 --- /dev/null +++ b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 000000000..dc9ada472 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000..28c6bf030 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000..f091b6b0b Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000..4cde12118 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000..d0ef06e7e Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000..dcdc2306c Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000..2ccbfd967 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000..c8f9ed8f5 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000..a6d6b8609 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000..75b2d164a Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000..c4df70d39 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000..6a84f41e1 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000..d0e1f5853 Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 000000000..0bedcf2fd --- /dev/null +++ b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 000000000..9da19eaca Binary files /dev/null and b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000..89c2725b7 --- /dev/null +++ b/spine-flutter/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/spine-flutter/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/spine-flutter/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f2e259c7c --- /dev/null +++ b/spine-flutter/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spine-flutter/example/ios/Runner/Base.lproj/Main.storyboard b/spine-flutter/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000..f3c28516f --- /dev/null +++ b/spine-flutter/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spine-flutter/example/ios/Runner/Info.plist b/spine-flutter/example/ios/Runner/Info.plist new file mode 100644 index 000000000..e2c1c6498 --- /dev/null +++ b/spine-flutter/example/ios/Runner/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Spine Flutter + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + spine_flutter_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/spine-flutter/example/ios/Runner/Runner-Bridging-Header.h b/spine-flutter/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 000000000..308a2a560 --- /dev/null +++ b/spine-flutter/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/spine-flutter/example/lib/animated_login.dart b/spine-flutter/example/lib/animated_login.dart new file mode 100644 index 000000000..373e3ea9d --- /dev/null +++ b/spine-flutter/example/lib/animated_login.dart @@ -0,0 +1,30 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; + +class AnimatedLogin extends StatelessWidget { + const AnimatedLogin({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + reportLeaks(); + final controller = SpineWidgetController(onInitialized: (controller) { + controller.skeleton.setSkinByName("nate"); + controller.skeleton.setToSetupPose(); + controller.animationState.setAnimationByName(0, "login/look-left-down", true); + }); + + return Scaffold( + appBar: AppBar(title: const Text('Animated login')), + body: Container( + margin: const EdgeInsets.all(15.0), + padding: const EdgeInsets.all(3.0), + decoration: BoxDecoration(border: Border.all(color: Colors.blueAccent)), + child: SpineWidget.fromAsset( + "assets/chibi/chibi-stickers.atlas", + "assets/chibi/chibi-stickers.skel", + controller, + boundsProvider: SkinAndAnimationBounds(skins: ["nate"], animation: "login/look-left-down"), + sizedByBounds: true, + ))); + } +} diff --git a/spine-flutter/example/lib/animation_state_events.dart b/spine-flutter/example/lib/animation_state_events.dart new file mode 100644 index 000000000..51b1a885a --- /dev/null +++ b/spine-flutter/example/lib/animation_state_events.dart @@ -0,0 +1,39 @@ +// ignore_for_file: avoid_print +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; + +class AnimationStateEvents extends StatelessWidget { + const AnimationStateEvents({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + reportLeaks(); + final controller = SpineWidgetController(onInitialized: (controller) { + controller.skeleton.setScaleX(0.5); + controller.skeleton.setScaleY(0.5); + controller.skeleton.findSlot("gun")?.setColor(Color(1, 0, 0, 1)); + controller.animationStateData.setDefaultMix(0.2); + controller.animationState.setAnimationByName(0, "walk", true).setListener((type, trackEntry, event) { + print("Walk animation event $type"); + }); + controller.animationState.addAnimationByName(0, "jump", false, 2); + controller.animationState.addAnimationByName(0, "run", true, 0).setListener((type, trackEntry, event) { + print("Run animation event $type"); + }); + controller.animationState.setListener((type, trackEntry, event) { + if (type == EventType.event) { + print( + "User event: { name: ${event?.getData().getName()}, intValue: ${event?.getIntValue()}, floatValue: intValue: ${event?.getFloatValue()}, stringValue: ${event?.getStringValue()} }"); + } + }); + print("Current: ${controller.animationState.getCurrent(0)?.getAnimation().getName()}"); + }); + + return Scaffold( + appBar: AppBar(title: const Text('Spineboy')), + body: Column(children: [ + const Text("See output in console!"), + Expanded(child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller)) + ])); + } +} diff --git a/spine-flutter/example/lib/debug_rendering.dart b/spine-flutter/example/lib/debug_rendering.dart new file mode 100644 index 000000000..3216140d1 --- /dev/null +++ b/spine-flutter/example/lib/debug_rendering.dart @@ -0,0 +1,23 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; + +class DebugRendering extends StatelessWidget { + const DebugRendering({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + reportLeaks(); + + const debugRenderer = DebugRenderer(); + final controller = SpineWidgetController(onInitialized: (controller) { + controller.animationState.setAnimationByName(0, "walk", true); + }, onAfterPaint: (controller, canvas, commands) { + debugRenderer.render(controller.drawable, canvas, commands); + }); + + return Scaffold( + appBar: AppBar(title: const Text('Debug Renderer')), + body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller), + ); + } +} diff --git a/spine-flutter/example/lib/dress_up.dart b/spine-flutter/example/lib/dress_up.dart new file mode 100644 index 000000000..9ac9d5ed0 --- /dev/null +++ b/spine-flutter/example/lib/dress_up.dart @@ -0,0 +1,104 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/painting.dart' as painting; +import 'package:raw_image_provider/raw_image_provider.dart'; + +class DressUp extends StatefulWidget { + const DressUp({Key? key}) : super(key: key); + + @override + DressUpState createState() => DressUpState(); +} + +class DressUpState extends State { + static const double thumbnailSize = 200; + late SkeletonDrawable _drawable; + Skin? _customSkin; + final Map _skinImages = {}; + final Map _selectedSkins = {}; + + @override + void initState() { + reportLeaks(); + super.initState(); + SkeletonDrawable.fromAsset("assets/mix-and-match.atlas", "assets/mix-and-match-pro.skel").then((drawable) async { + _drawable = drawable; + for (var skin in drawable.skeletonData.getSkins()) { + if (skin.getName() == "default") continue; + var skeleton = drawable.skeleton; + skeleton.setSkin(skin); + skeleton.setToSetupPose(); + skeleton.updateWorldTransform(); + _skinImages[skin.getName()] = await drawable.renderToRawImageData(thumbnailSize, thumbnailSize, 0xffffffff); + _selectedSkins[skin.getName()] = false; + } + _toggleSkin("full-skins/girl"); + setState(() {}); + }); + } + + void _toggleSkin(String skinName) { + _selectedSkins[skinName] = !_selectedSkins[skinName]!; + if (_customSkin != null) _customSkin?.dispose(); + _customSkin = Skin("custom-skin"); + for (var skinName in _selectedSkins.keys) { + if (_selectedSkins[skinName] == true) { + var skin = _drawable.skeletonData.findSkin(skinName); + if (skin != null) _customSkin?.addSkin(skin); + } + } + _drawable.skeleton.setSkin(_customSkin!); + _drawable.skeleton.setToSetupPose(); + } + + @override + Widget build(BuildContext context) { + final controller = SpineWidgetController(onInitialized: (controller) { + controller.animationState.setAnimationByName(0, "dance", true); + }); + + return Scaffold( + appBar: AppBar(title: const Text('Dress Up')), + body: _skinImages.isEmpty + ? const SizedBox() + : Row(children: [ + SizedBox( + width: thumbnailSize, + child: ListView( + children: _skinImages.keys.map((skinName) { + var rawImageData = _skinImages[skinName]!; + var image = Image(image: RawImageProvider(rawImageData)); + var box = SizedBox(width: 200, height: 200, child: image); + return GestureDetector( + onTap: () { + _toggleSkin(skinName); + setState(() {}); + }, + child: _selectedSkins[skinName] == true + ? box + // Does not work on web. + //: ColorFiltered(colorFilter: const ColorFilter.mode(Colors.grey, painting.BlendMode.saturation,), child: box) + : Container( + foregroundDecoration: const BoxDecoration( + color: Colors.grey, + backgroundBlendMode: painting.BlendMode.saturation, + ), + child: box)); + }).toList()), + ), + Expanded( + child: SpineWidget.fromDrawable( + _drawable, + controller, + boundsProvider: SkinAndAnimationBounds(skins: ["full-skins/girl"]), + )) + ])); + } + + @override + void dispose() { + super.dispose(); + _drawable.dispose(); + _customSkin?.dispose(); + } +} diff --git a/spine-flutter/example/lib/flame_example.dart b/spine-flutter/example/lib/flame_example.dart new file mode 100644 index 000000000..e1b668ce8 --- /dev/null +++ b/spine-flutter/example/lib/flame_example.dart @@ -0,0 +1,151 @@ +import 'dart:math'; + +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flame/components.dart'; +import 'package:flame/game.dart'; +import 'package:flutter/material.dart'; + +class SpineComponent extends PositionComponent { + final BoundsProvider _boundsProvider; + final SkeletonDrawable _drawable; + late final Bounds _bounds; + final bool _ownsDrawable; + + SpineComponent( + this._drawable, { + bool ownsDrawable = true, + BoundsProvider boundsProvider = const SetupPoseBounds(), + super.position, + super.scale, + double super.angle = 0.0, + Anchor super.anchor = Anchor.topLeft, + super.children, + super.priority, + }) : _ownsDrawable = ownsDrawable, + _boundsProvider = boundsProvider { + _drawable.update(0); + _bounds = _boundsProvider.computeBounds(_drawable); + size = Vector2(_bounds.width, _bounds.height); + } + + static Future fromAssets( + String atlasFile, + String skeletonFile, { + AssetBundle? bundle, + BoundsProvider boundsProvider = const SetupPoseBounds(), + Vector2? position, + Vector2? scale, + double angle = 0.0, + Anchor anchor = Anchor.topLeft, + Iterable? children, + int? priority, + }) async { + return SpineComponent(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle), + ownsDrawable: true, + boundsProvider: boundsProvider, + position: position, + scale: scale, + angle: angle, + anchor: anchor, + children: children, + priority: priority); + } + + void dispose() { + if (_ownsDrawable) { + _drawable.dispose(); + } + } + + @override + void update(double dt) { + _drawable.update(dt); + } + + @override + void render(Canvas canvas) { + canvas.save(); + canvas.translate(-_bounds.x, -_bounds.y); + _drawable.renderToCanvas(canvas); + canvas.restore(); + } + + get animationState => _drawable.animationState; + + get animationStateData => _drawable.animationStateData; + + get skeleton => _drawable.skeleton; +} + +class SimpleFlameExample extends FlameGame { + late final SpineComponent spineboy; + + @override + Future onLoad() async { + // Load the Spineboy atlas and skeleton data from asset files + // and create a SpineComponent from them, scaled down and + // centered on the screen + spineboy = await SpineComponent.fromAssets("assets/spineboy.atlas", "assets/spineboy-pro.skel", + scale: Vector2(0.4, 0.4), anchor: Anchor.center, position: Vector2(size.x / 2, size.y / 2)); + + // Set the "walk" animation on track 0 in looping mode + spineboy.animationState.setAnimationByName(0, "walk", true); + await add(spineboy); + } + + @override + void onDetach() { + // Dispose the native resources that have been loaded for spineboy. + spineboy.dispose(); + } +} + +class PreloadAndShareSpineDataExample extends FlameGame { + late final SkeletonData cachedSkeletonData; + late final Atlas cachedAtlas; + late final List spineboys = []; + + @override + Future onLoad() async { + // Pre-load the atlas and skeleton data once. + cachedAtlas = await Atlas.fromAsset("assets/spineboy.atlas"); + cachedSkeletonData = await SkeletonData.fromAsset(cachedAtlas, "assets/spineboy-pro.skel"); + + // Instantiate many spineboys from the pre-loaded data. Each SpineComponent + // gets their own SkeletonDrawable copy derived from the cached data. The + // SkeletonDrawable copies do not own the underlying skeleton data and atlas. + final rng = Random(); + for (int i = 0; i < 100; i++) { + final drawable = SkeletonDrawable(cachedAtlas, cachedSkeletonData, false); + final scale = 0.1 + rng.nextDouble() * 0.2; + final position = Vector2(rng.nextDouble() * size.x, rng.nextDouble() * size.y); + final spineboy = SpineComponent(drawable, scale: Vector2(scale, scale), position: position); + spineboy.animationState.setAnimationByName(0, "walk", true); + spineboys.add(spineboy); + await add(spineboy); + } + } + + @override + void onDetach() { + // Dispose the pre-loaded atlas and skeleton data when the game/scene is removed. + cachedAtlas.dispose(); + cachedSkeletonData.dispose(); + + // Dispose each spineboy and its internal SkeletonDrawable. + for (final spineboy in spineboys) { + spineboy.dispose(); + } + } +} + +class SpineFlameGameWidget extends StatelessWidget { + final FlameGame game; + + const SpineFlameGameWidget(this.game, {super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold(appBar: AppBar(title: const Text('Flame Integration')), body: GameWidget(game: game)); + } +} diff --git a/spine-flutter/example/lib/ik_following.dart b/spine-flutter/example/lib/ik_following.dart new file mode 100644 index 000000000..40277e8bd --- /dev/null +++ b/spine-flutter/example/lib/ik_following.dart @@ -0,0 +1,52 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; + +class IkFollowing extends StatefulWidget { + const IkFollowing({Key? key}) : super(key: key); + + @override + IkFollowingState createState() => IkFollowingState(); +} + +class IkFollowingState extends State { + late SpineWidgetController controller; + Offset? crossHairPosition; + + @override + void initState() { + super.initState(); + + controller = SpineWidgetController(onInitialized: (controller) { + // Set the walk animation on track 0, let it loop + controller.animationState.setAnimationByName(0, "walk", true); + controller.animationState.setAnimationByName(1, "aim", true); + }, onAfterUpdateWorldTransforms: (controller) { + var worldPosition = crossHairPosition; + if (worldPosition == null) return; + var bone = controller.skeleton.findBone("crosshair"); + if (bone == null) return; + var parent = bone.getParent(); + if (parent == null) return; + var position = parent.worldToLocal(worldPosition.dx, worldPosition.dy); + bone.setX(position.x); + bone.setY(position.y); + }); + } + + void _updateBonePosition(Offset position) { + crossHairPosition = controller.toSkeletonCoordinates(position); + } + + @override + Widget build(BuildContext context) { + reportLeaks(); + + return Scaffold( + appBar: AppBar(title: const Text('IK Following')), + body: GestureDetector( + onPanDown: (drag) => _updateBonePosition(drag.localPosition), + onPanUpdate: (drag) => _updateBonePosition(drag.localPosition), + child: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller), + )); + } +} diff --git a/spine-flutter/example/lib/main.dart b/spine-flutter/example/lib/main.dart new file mode 100644 index 000000000..87453379e --- /dev/null +++ b/spine-flutter/example/lib/main.dart @@ -0,0 +1,139 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; +import 'package:spine_flutter_example/animated_login.dart'; +import 'package:spine_flutter_example/debug_rendering.dart'; + +import 'animation_state_events.dart'; +import 'dress_up.dart'; +import 'flame_example.dart'; +import 'ik_following.dart'; +import 'pause_play_animation.dart'; +import 'simple_animation.dart'; + +class ExampleSelector extends StatelessWidget { + const ExampleSelector({super.key}); + + @override + Widget build(BuildContext context) { + const spacer = SizedBox(height: 10); + return Scaffold( + appBar: AppBar(title: const Text('Spine Examples')), + body: Center( + child: Column(mainAxisSize: MainAxisSize.min, children: [ + ElevatedButton( + child: const Text('Simple Animation'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const SimpleAnimation(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Pause/Play animation'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const PlayPauseAnimation(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Animation State Listener'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const AnimationStateEvents(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Debug Rendering'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DebugRendering(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Animated login'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const AnimatedLogin(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Dress Up'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DressUp(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('IK Following'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const IkFollowing(), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Flame: Simple Example'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SpineFlameGameWidget(SimpleFlameExample()), + ), + ); + }, + ), + spacer, + ElevatedButton( + child: const Text('Flame: Pre-load and share Spine data'), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SpineFlameGameWidget(PreloadAndShareSpineDataExample()), + ), + ); + }, + ), + spacer + ]))); + } +} + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await initSpineFlutter(enableMemoryDebugging: false); + runApp(const MaterialApp(title: "Spine Examples", home: ExampleSelector())); +} diff --git a/spine-flutter/example/lib/pause_play_animation.dart b/spine-flutter/example/lib/pause_play_animation.dart new file mode 100644 index 000000000..02ccf01ca --- /dev/null +++ b/spine-flutter/example/lib/pause_play_animation.dart @@ -0,0 +1,49 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; + +class PlayPauseAnimation extends StatefulWidget { + const PlayPauseAnimation({Key? key}) : super(key: key); + + @override + PlayPauseAnimationState createState() => PlayPauseAnimationState(); +} + +class PlayPauseAnimationState extends State { + late SpineWidgetController controller; + + @override + void initState() { + super.initState(); + controller = SpineWidgetController(onInitialized: (controller) { + controller.animationState.setAnimationByName(0, "flying", true); + }); + } + + void _togglePlay() { + if (controller.isPlaying) { + controller.pause(); + } else { + controller.resume(); + } + setState(() {}); + } + + @override + Widget build(BuildContext context) { + reportLeaks(); + + return Scaffold( + appBar: AppBar(title: const Text('Play/Pause')), + body: SpineWidget.fromAsset( + "assets/dragon.atlas", + "assets/dragon-ess.skel", + controller, + boundsProvider: SkinAndAnimationBounds(animation: "flying"), + ), + floatingActionButton: FloatingActionButton( + onPressed: _togglePlay, + child: Icon(controller.isPlaying ? Icons.pause : Icons.play_arrow), + ), + ); + } +} diff --git a/spine-flutter/example/lib/simple_animation.dart b/spine-flutter/example/lib/simple_animation.dart new file mode 100644 index 000000000..07c9cdb6f --- /dev/null +++ b/spine-flutter/example/lib/simple_animation.dart @@ -0,0 +1,20 @@ +import 'package:spine_flutter/spine_flutter.dart'; +import 'package:flutter/material.dart'; + +class SimpleAnimation extends StatelessWidget { + const SimpleAnimation({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + reportLeaks(); + final controller = SpineWidgetController(onInitialized: (controller) { + // Set the walk animation on track 0, let it loop + controller.animationState.setAnimationByName(0, "walk", true); + }); + + return Scaffold( + appBar: AppBar(title: const Text('Simple Animation')), + body: SpineWidget.fromAsset("assets/spineboy.atlas", "assets/spineboy-pro.skel", controller) + ); + } +} diff --git a/spine-flutter/example/linux/.gitignore b/spine-flutter/example/linux/.gitignore new file mode 100644 index 000000000..d3896c984 --- /dev/null +++ b/spine-flutter/example/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/spine-flutter/example/linux/CMakeLists.txt b/spine-flutter/example/linux/CMakeLists.txt new file mode 100644 index 000000000..0bb3b1e1a --- /dev/null +++ b/spine-flutter/example/linux/CMakeLists.txt @@ -0,0 +1,138 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "spine_flutter_example") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.spine_flutter") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/spine-flutter/example/linux/flutter/CMakeLists.txt b/spine-flutter/example/linux/flutter/CMakeLists.txt new file mode 100644 index 000000000..d5bd01648 --- /dev/null +++ b/spine-flutter/example/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/spine-flutter/example/linux/flutter/generated_plugin_registrant.cc b/spine-flutter/example/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000..e71a16d23 --- /dev/null +++ b/spine-flutter/example/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/spine-flutter/example/linux/flutter/generated_plugin_registrant.h b/spine-flutter/example/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000..e0f0a47bc --- /dev/null +++ b/spine-flutter/example/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/spine-flutter/example/linux/flutter/generated_plugins.cmake b/spine-flutter/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000..55f28b8cb --- /dev/null +++ b/spine-flutter/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST + spine_flutter +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/spine-flutter/example/linux/main.cc b/spine-flutter/example/linux/main.cc new file mode 100644 index 000000000..e7c5c5437 --- /dev/null +++ b/spine-flutter/example/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/spine-flutter/example/linux/my_application.cc b/spine-flutter/example/linux/my_application.cc new file mode 100644 index 000000000..c14c8f0d5 --- /dev/null +++ b/spine-flutter/example/linux/my_application.cc @@ -0,0 +1,104 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "spine_flutter_example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "spine_flutter_example"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/spine-flutter/example/linux/my_application.h b/spine-flutter/example/linux/my_application.h new file mode 100644 index 000000000..72271d5e4 --- /dev/null +++ b/spine-flutter/example/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/spine-flutter/example/macos/.gitignore b/spine-flutter/example/macos/.gitignore new file mode 100644 index 000000000..746adbb6b --- /dev/null +++ b/spine-flutter/example/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/spine-flutter/example/macos/Flutter/Flutter-Debug.xcconfig b/spine-flutter/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000..4b81f9b2d --- /dev/null +++ b/spine-flutter/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/spine-flutter/example/macos/Flutter/Flutter-Release.xcconfig b/spine-flutter/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000..5caa9d157 --- /dev/null +++ b/spine-flutter/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/spine-flutter/example/macos/Flutter/GeneratedPluginRegistrant.swift b/spine-flutter/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 000000000..cccf817a5 --- /dev/null +++ b/spine-flutter/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { +} diff --git a/spine-flutter/example/macos/Podfile b/spine-flutter/example/macos/Podfile new file mode 100644 index 000000000..049abe295 --- /dev/null +++ b/spine-flutter/example/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/spine-flutter/example/macos/Podfile.lock b/spine-flutter/example/macos/Podfile.lock new file mode 100644 index 000000000..a13caa1c6 --- /dev/null +++ b/spine-flutter/example/macos/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - FlutterMacOS (1.0.0) + - spine_flutter (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - spine_flutter (from `Flutter/ephemeral/.symlinks/plugins/spine_flutter/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + spine_flutter: + :path: Flutter/ephemeral/.symlinks/plugins/spine_flutter/macos + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + spine_flutter: 9cf72fc0088c2820e80a4d3dc83ba29ac58f40d1 + +PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 + +COCOAPODS: 1.11.3 diff --git a/spine-flutter/example/macos/Runner.xcodeproj/project.pbxproj b/spine-flutter/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..06f931d0a --- /dev/null +++ b/spine-flutter/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,633 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + BFA9447ED4274BACBC56C015 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 208CD84229398A3D11917760 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 208CD84229398A3D11917760 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* spine_flutter_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = spine_flutter_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 57F2A1E5134EB334541ADAEF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + B6AF292002FE0B8EED5F9705 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + F08BF403BB28AE2FB75B3EC9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BFA9447ED4274BACBC56C015 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 519971AFDC2707EADE042788 /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* spine_flutter_example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 519971AFDC2707EADE042788 /* Pods */ = { + isa = PBXGroup; + children = ( + 57F2A1E5134EB334541ADAEF /* Pods-Runner.debug.xcconfig */, + B6AF292002FE0B8EED5F9705 /* Pods-Runner.release.xcconfig */, + F08BF403BB28AE2FB75B3EC9 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 208CD84229398A3D11917760 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9866358D974AB17940F6A2BA /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + 3AE90734F9AAEE77C4A64527 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* spine_flutter_example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; + 3AE90734F9AAEE77C4A64527 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9866358D974AB17940F6A2BA /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/spine-flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/spine-flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..21a3cc14c --- /dev/null +++ b/spine-flutter/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/spine-flutter/example/macos/Runner/AppDelegate.swift b/spine-flutter/example/macos/Runner/AppDelegate.swift new file mode 100644 index 000000000..d53ef6437 --- /dev/null +++ b/spine-flutter/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..a2ec33f19 --- /dev/null +++ b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000..3c4935a7c Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000..ed4cc1642 Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000..483be6138 Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000..bcbf36df2 Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000..9c0a65286 Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000..e71a72613 Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000..8a31fe2dd Binary files /dev/null and b/spine-flutter/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/spine-flutter/example/macos/Runner/Base.lproj/MainMenu.xib b/spine-flutter/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 000000000..80e867a4e --- /dev/null +++ b/spine-flutter/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spine-flutter/example/macos/Runner/Configs/AppInfo.xcconfig b/spine-flutter/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 000000000..55b23a5fe --- /dev/null +++ b/spine-flutter/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = spine_flutter_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.spineFlutterExample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. diff --git a/spine-flutter/example/macos/Runner/Configs/Debug.xcconfig b/spine-flutter/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 000000000..36b0fd946 --- /dev/null +++ b/spine-flutter/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/spine-flutter/example/macos/Runner/Configs/Release.xcconfig b/spine-flutter/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 000000000..dff4f4956 --- /dev/null +++ b/spine-flutter/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/spine-flutter/example/macos/Runner/Configs/Warnings.xcconfig b/spine-flutter/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 000000000..42bcbf478 --- /dev/null +++ b/spine-flutter/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/spine-flutter/example/macos/Runner/DebugProfile.entitlements b/spine-flutter/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 000000000..4eac53fe0 --- /dev/null +++ b/spine-flutter/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/spine-flutter/example/macos/Runner/Info.plist b/spine-flutter/example/macos/Runner/Info.plist new file mode 100644 index 000000000..4789daa6a --- /dev/null +++ b/spine-flutter/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/spine-flutter/example/macos/Runner/MainFlutterWindow.swift b/spine-flutter/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 000000000..2722837ec --- /dev/null +++ b/spine-flutter/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/spine-flutter/example/macos/Runner/Release.entitlements b/spine-flutter/example/macos/Runner/Release.entitlements new file mode 100644 index 000000000..852fa1a47 --- /dev/null +++ b/spine-flutter/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/spine-flutter/example/pubspec.lock b/spine-flutter/example/pubspec.lock new file mode 100644 index 000000000..77bfaa806 --- /dev/null +++ b/spine-flutter/example/pubspec.lock @@ -0,0 +1,215 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" + source: hosted + version: "1.0.5" + ffi: + dependency: transitive + description: + name: ffi + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + flame: + dependency: "direct main" + description: + name: flame + sha256: "0c55f8d704f09536125c811a19d9aab7407dce245b2bfb507e84296c1c996202" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + url: "https://pub.dev" + source: hosted + version: "2.0.1" + http: + dependency: transitive + description: + name: http + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" + source: hosted + version: "0.13.5" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + inject_js: + dependency: transitive + description: + name: inject_js + sha256: "3ab213e2c76375a611f57eb0044d32c6e18c5091d52510e7fe9f88f6bee83d19" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + lints: + dependency: transitive + description: + name: lints + sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + ordered_set: + dependency: transitive + description: + name: ordered_set + sha256: "74b0454418f58c34c8e527d91fb1ef571297dbcd5d3b4e5f983dc884e39cdf85" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + raw_image_provider: + dependency: "direct main" + description: + name: raw_image_provider + sha256: d5b20d69e8a998a4dc846a3d35dca8760121d18b6895233fca52f9055a9a7e8e + url: "https://pub.dev" + source: hosted + version: "0.2.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + spine_flutter: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "4.2.11" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + web_ffi_fork: + dependency: transitive + description: + name: web_ffi_fork + sha256: "7466228b7fc6a29ee1b5f6ab7ee2473847367a70fb523eb1a7c1d7a6a9841589" + url: "https://pub.dev" + source: hosted + version: "0.7.4" +sdks: + dart: ">=2.18.0 <4.0.0" + flutter: ">=3.7.0" diff --git a/spine-flutter/example/pubspec.yaml b/spine-flutter/example/pubspec.yaml new file mode 100644 index 000000000..526cd7511 --- /dev/null +++ b/spine-flutter/example/pubspec.yaml @@ -0,0 +1,26 @@ +name: spine_flutter_example +description: Demonstrates how to use the spine_flutter plugin. +publish_to: 'none' +version: 1.0.0+1 + +environment: + sdk: ">=2.17.6 <3.0.0" + flutter: ">=3.7.0" + +dependencies: + flutter: + sdk: flutter + + spine_flutter: + path: ../ + cupertino_icons: ^1.0.2 + flame: ^1.4.0 + raw_image_provider: ^0.2.0 + +dev_dependencies: + flutter_lints: ^2.0.0 + +flutter: + uses-material-design: true + assets: + - assets/ \ No newline at end of file diff --git a/spine-flutter/example/web/favicon.png b/spine-flutter/example/web/favicon.png new file mode 100644 index 000000000..8aaa46ac1 Binary files /dev/null and b/spine-flutter/example/web/favicon.png differ diff --git a/spine-flutter/example/web/icons/Icon-192.png b/spine-flutter/example/web/icons/Icon-192.png new file mode 100644 index 000000000..b749bfef0 Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-192.png differ diff --git a/spine-flutter/example/web/icons/Icon-512.png b/spine-flutter/example/web/icons/Icon-512.png new file mode 100644 index 000000000..88cfd48df Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-512.png differ diff --git a/spine-flutter/example/web/icons/Icon-maskable-192.png b/spine-flutter/example/web/icons/Icon-maskable-192.png new file mode 100644 index 000000000..eb9b4d76e Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-maskable-192.png differ diff --git a/spine-flutter/example/web/icons/Icon-maskable-512.png b/spine-flutter/example/web/icons/Icon-maskable-512.png new file mode 100644 index 000000000..d69c56691 Binary files /dev/null and b/spine-flutter/example/web/icons/Icon-maskable-512.png differ diff --git a/spine-flutter/example/web/index.html b/spine-flutter/example/web/index.html new file mode 100644 index 000000000..41b3bc336 --- /dev/null +++ b/spine-flutter/example/web/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + example + + + + + + + + + + diff --git a/spine-flutter/example/web/manifest.json b/spine-flutter/example/web/manifest.json new file mode 100644 index 000000000..096edf8fe --- /dev/null +++ b/spine-flutter/example/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/spine-flutter/example/windows/.gitignore b/spine-flutter/example/windows/.gitignore new file mode 100644 index 000000000..d492d0d98 --- /dev/null +++ b/spine-flutter/example/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/spine-flutter/example/windows/CMakeLists.txt b/spine-flutter/example/windows/CMakeLists.txt new file mode 100644 index 000000000..b7eb58b41 --- /dev/null +++ b/spine-flutter/example/windows/CMakeLists.txt @@ -0,0 +1,101 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(spine_flutter_example LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "spine_flutter_example") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/spine-flutter/example/windows/flutter/CMakeLists.txt b/spine-flutter/example/windows/flutter/CMakeLists.txt new file mode 100644 index 000000000..930d2071a --- /dev/null +++ b/spine-flutter/example/windows/flutter/CMakeLists.txt @@ -0,0 +1,104 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/spine-flutter/example/windows/flutter/generated_plugin_registrant.cc b/spine-flutter/example/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000..8b6d4680a --- /dev/null +++ b/spine-flutter/example/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/spine-flutter/example/windows/flutter/generated_plugin_registrant.h b/spine-flutter/example/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000..dc139d85a --- /dev/null +++ b/spine-flutter/example/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/spine-flutter/example/windows/flutter/generated_plugins.cmake b/spine-flutter/example/windows/flutter/generated_plugins.cmake new file mode 100644 index 000000000..dca11f385 --- /dev/null +++ b/spine-flutter/example/windows/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST + spine_flutter +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/spine-flutter/example/windows/runner/CMakeLists.txt b/spine-flutter/example/windows/runner/CMakeLists.txt new file mode 100644 index 000000000..b9e550fba --- /dev/null +++ b/spine-flutter/example/windows/runner/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/spine-flutter/example/windows/runner/Runner.rc b/spine-flutter/example/windows/runner/Runner.rc new file mode 100644 index 000000000..5ac8730bb --- /dev/null +++ b/spine-flutter/example/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "spine_flutter_example" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "spine_flutter_example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "spine_flutter_example.exe" "\0" + VALUE "ProductName", "spine_flutter_example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/spine-flutter/example/windows/runner/flutter_window.cpp b/spine-flutter/example/windows/runner/flutter_window.cpp new file mode 100644 index 000000000..b43b9095e --- /dev/null +++ b/spine-flutter/example/windows/runner/flutter_window.cpp @@ -0,0 +1,61 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/spine-flutter/example/windows/runner/flutter_window.h b/spine-flutter/example/windows/runner/flutter_window.h new file mode 100644 index 000000000..6da0652f0 --- /dev/null +++ b/spine-flutter/example/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/spine-flutter/example/windows/runner/main.cpp b/spine-flutter/example/windows/runner/main.cpp new file mode 100644 index 000000000..dc3367154 --- /dev/null +++ b/spine-flutter/example/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"spine_flutter_example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/spine-flutter/example/windows/runner/resource.h b/spine-flutter/example/windows/runner/resource.h new file mode 100644 index 000000000..66a65d1e4 --- /dev/null +++ b/spine-flutter/example/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/spine-flutter/example/windows/runner/resources/app_icon.ico b/spine-flutter/example/windows/runner/resources/app_icon.ico new file mode 100644 index 000000000..c04e20caf Binary files /dev/null and b/spine-flutter/example/windows/runner/resources/app_icon.ico differ diff --git a/spine-flutter/example/windows/runner/runner.exe.manifest b/spine-flutter/example/windows/runner/runner.exe.manifest new file mode 100644 index 000000000..c977c4a42 --- /dev/null +++ b/spine-flutter/example/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/spine-flutter/example/windows/runner/utils.cpp b/spine-flutter/example/windows/runner/utils.cpp new file mode 100644 index 000000000..f5bf9fa0f --- /dev/null +++ b/spine-flutter/example/windows/runner/utils.cpp @@ -0,0 +1,64 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/spine-flutter/example/windows/runner/utils.h b/spine-flutter/example/windows/runner/utils.h new file mode 100644 index 000000000..3879d5475 --- /dev/null +++ b/spine-flutter/example/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/spine-flutter/example/windows/runner/win32_window.cpp b/spine-flutter/example/windows/runner/win32_window.cpp new file mode 100644 index 000000000..c10f08dc7 --- /dev/null +++ b/spine-flutter/example/windows/runner/win32_window.cpp @@ -0,0 +1,245 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/spine-flutter/example/windows/runner/win32_window.h b/spine-flutter/example/windows/runner/win32_window.h new file mode 100644 index 000000000..17ba43112 --- /dev/null +++ b/spine-flutter/example/windows/runner/win32_window.h @@ -0,0 +1,98 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/spine-flutter/ffigen.yaml b/spine-flutter/ffigen.yaml new file mode 100644 index 000000000..d6c9fcac9 --- /dev/null +++ b/spine-flutter/ffigen.yaml @@ -0,0 +1,21 @@ +# Run with `dart run ffigen --config ffigen.yaml`. +name: SpineFlutterBindings +description: | + Bindings for `src/spine_flutter.h`. + + Regenerate bindings with `dart run ffigen --config ffigen.yaml`. +output: 'lib/spine_flutter_bindings_generated.dart' +llvm-path: + - '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/' +headers: + entry-points: + - 'src/spine_flutter.h' + include-directives: + - 'src/spine_flutter.h' +preamble: | + // ignore_for_file: always_specify_types, constant_identifier_names + // ignore_for_file: camel_case_types + // ignore_for_file: non_constant_identifier_names +comments: + style: any + length: full diff --git a/spine-flutter/ios/Classes/spine_flutter.cpp b/spine-flutter/ios/Classes/spine_flutter.cpp new file mode 100644 index 000000000..ac5716e5d --- /dev/null +++ b/spine-flutter/ios/Classes/spine_flutter.cpp @@ -0,0 +1,3 @@ +// Relative import to be able to reuse the C sources. +// See the comment in ../{projectName}}.podspec for more information. +#include "../../src/spine_flutter.cpp" diff --git a/spine-flutter/ios/spine_flutter.podspec b/spine-flutter/ios/spine_flutter.podspec new file mode 100644 index 000000000..7c725addc --- /dev/null +++ b/spine-flutter/ios/spine_flutter.podspec @@ -0,0 +1,29 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint spine_flutter.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'spine_flutter' + s.version = '0.0.1' + s.summary = 'A new Flutter FFI plugin project.' + s.description = <<-DESC +A new Flutter FFI plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + + # This will ensure the source files in Classes/ are included in the native + # builds of apps using this FFI plugin. Podspec does not support relative + # paths, so Classes contains a forwarder C file that relatively imports + # `../src/*` so that the C sources can be shared among all target platforms. + s.source = { :path => '.' } + s.source_files = 'Classes/**/*.{cpp}' + s.xcconfig = { 'HEADER_SEARCH_PATHS' => '"' + __dir__ + '/Classes/spine-cpp/include"' } + s.dependency 'Flutter' + s.platform = :ios, '9.0' + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } + s.swift_version = '5.0' +end diff --git a/spine-flutter/lib/assets/libspine_flutter.js b/spine-flutter/lib/assets/libspine_flutter.js new file mode 100644 index 000000000..3aee9ad61 --- /dev/null +++ b/spine-flutter/lib/assets/libspine_flutter.js @@ -0,0 +1,254 @@ + +var libspine_flutter = (() => { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(libspine_flutter) { + libspine_flutter = libspine_flutter || {}; + + +var a;a||(a=typeof libspine_flutter !== 'undefined' ? libspine_flutter : {});var h,k;a.ready=new Promise(function(b,c){h=b;k=c});var l=Object.assign({},a),m="object"==typeof window,n="function"==typeof importScripts,p="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,q="",r,t,u; +if(p){q=n?require("path").dirname(q)+"/":__dirname+"/";var fs,v;"function"===typeof require&&(fs=require("fs"),v=require("path"));r=(b,c)=>{b=v.normalize(b);return fs.readFileSync(b,c?void 0:"utf8")};u=b=>{b=r(b,!0);b.buffer||(b=new Uint8Array(b));return b};t=(b,c,d)=>{b=v.normalize(b);fs.readFile(b,function(e,f){e?d(e):c(f.buffer)})};1{var c=new XMLHttpRequest;c.open("GET",b,!1);c.send(null);return c.responseText},n&&(u=b=>{var c=new XMLHttpRequest;c.open("GET",b,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)}), +t=(b,c,d)=>{var e=new XMLHttpRequest;e.open("GET",b,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?c(e.response):d()};e.onerror=d;e.send(null)};var aa=a.print||console.log.bind(console),x=a.printErr||console.warn.bind(console);Object.assign(a,l);l=null;var y;a.wasmBinary&&(y=a.wasmBinary);var noExitRuntime=a.noExitRuntime||!0;"object"!=typeof WebAssembly&&z("no native wasm support detected"); +var A,B=!1,D="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0; +function E(b,c){for(var d=c+NaN,e=c;b[e]&&!(e>=d);)++e;if(16f?d+=String.fromCharCode(f):(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else d+=String.fromCharCode(f)}return d}var F,G,H,I,J,K,L,M; +function N(){var b=A.buffer;F=b;a.HEAP8=G=new Int8Array(b);a.HEAP16=I=new Int16Array(b);a.HEAP32=J=new Int32Array(b);a.HEAPU8=H=new Uint8Array(b);a.HEAPU16=new Uint16Array(b);a.HEAPU32=K=new Uint32Array(b);a.HEAPF32=L=new Float32Array(b);a.HEAPF64=M=new Float64Array(b)}var ba=[],ca=[],da=[];function ea(){var b=a.preRun.shift();ba.unshift(b)}var O=0,P=null,R=null; +function z(b){if(a.onAbort)a.onAbort(b);b="Aborted("+b+")";x(b);B=!0;b=new WebAssembly.RuntimeError(b+". Build with -sASSERTIONS for more info.");k(b);throw b;}function fa(){return S.startsWith("data:application/octet-stream;base64,")}var S;S="libspine_flutter.wasm";if(!fa()){var ha=S;S=a.locateFile?a.locateFile(ha,q):q+ha}function ia(){var b=S;try{if(b==S&&y)return new Uint8Array(y);if(u)return u(b);throw"both async and sync fetching of the wasm failed";}catch(c){z(c)}} +function ja(){if(!y&&(m||n)){if("function"==typeof fetch&&!S.startsWith("file://"))return fetch(S,{credentials:"same-origin"}).then(function(b){if(!b.ok)throw"failed to load wasm binary file at '"+S+"'";return b.arrayBuffer()}).catch(function(){return ia()});if(t)return new Promise(function(b,c){t(S,function(d){b(new Uint8Array(d))},c)})}return Promise.resolve().then(function(){return ia()})}var T,U; +function w(b){this.name="ExitStatus";this.message="Program terminated with exit("+b+")";this.status=b}a.ExitStatus=w;function V(b){for(;0>0];case "i8":return G[b>>0];case "i16":return I[b>>1];case "i32":return J[b>>2];case "i64":return J[b>>2];case "float":return L[b>>2];case "double":return M[b>>3];case "*":return K[b>>2];default:z("invalid type for getValue: "+c)}return null}; +a.setValue=function(b,c,d="i8"){d.endsWith("*")&&(d="*");switch(d){case "i1":G[b>>0]=c;break;case "i8":G[b>>0]=c;break;case "i16":I[b>>1]=c;break;case "i32":J[b>>2]=c;break;case "i64":U=[c>>>0,(T=c,1<=+Math.abs(T)?0>>0:~~+Math.ceil((T-+(~~T>>>0))/4294967296)>>>0:0)];J[b>>2]=U[0];J[b+4>>2]=U[1];break;case "float":L[b>>2]=c;break;case "double":M[b>>3]=c;break;case "*":K[b>>2]=c;break;default:z("invalid type for setValue: "+d)}}; +function ka(b,c,d,e){z("Assertion failed: "+(b?E(H,b):"")+", at: "+[c?c?E(H,c):"":"unknown filename",d,e?e?E(H,e):"":"unknown function"])}a.___assert_fail=ka;function la(){z("")}a._abort=la;function ma(b,c,d){H.copyWithin(b,c,c+d)}a._emscripten_memcpy_big=ma;a.getHeapMax=function(){return 2147483648};function oa(b){try{return A.grow(b-F.byteLength+65535>>>16),N(),1}catch(c){}}a.emscripten_realloc_buffer=oa; +function pa(b){var c=H.length;b>>>=0;if(2147483648=d;d*=2){var e=c*(1+.2/d);e=Math.min(e,b+100663296);var f=Math;e=Math.max(b,e);if(oa(f.min.call(f,2147483648,e+(65536-e%65536)%65536)))return!0}return!1}a._emscripten_resize_heap=pa;var W=[null,[],[]];a.printCharBuffers=W;function X(b,c){var d=W[b];0===c||10===c?((1===b?aa:x)(E(d,0)),d.length=0):d.push(c)}a.printChar=X;a.flush_NO_FILESYSTEM=function(){W[1].length&&X(1,10);W[2].length&&X(2,10)}; +var Y={g:void 0,get:function(){Y.g+=4;return J[Y.g-4>>2]},h:function(b){return b?E(H,b):""}};a.SYSCALLS=Y;function qa(b,c,d,e){for(var f=0,g=0;g>2],na=K[c+4>>2];c+=8;for(var Q=0;Q>2]=f;return 0}a._fd_write=qa;var ra={__assert_fail:ka,abort:la,emscripten_memcpy_big:ma,emscripten_resize_heap:pa,fd_write:qa}; +(function(){function b(f){a.asm=f.exports;A=a.asm.memory;N();ca.unshift(a.asm.__wasm_call_ctors);O--;a.monitorRunDependencies&&a.monitorRunDependencies(O);0==O&&(null!==P&&(clearInterval(P),P=null),R&&(f=R,R=null,f()))}function c(f){b(f.instance)}function d(f){return ja().then(function(g){return WebAssembly.instantiate(g,e)}).then(function(g){return g}).then(f,function(g){x("failed to asynchronously prepare wasm: "+g);z(g)})}var e={env:ra,wasi_snapshot_preview1:ra};O++;a.monitorRunDependencies&&a.monitorRunDependencies(O); +if(a.instantiateWasm)try{return a.instantiateWasm(e,b)}catch(f){x("Module.instantiateWasm callback failed with error: "+f),k(f)}(function(){return y||"function"!=typeof WebAssembly.instantiateStreaming||fa()||S.startsWith("file://")||p||"function"!=typeof fetch?d(c):fetch(S,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(c,function(g){x("wasm streaming compile failed: "+g);x("falling back to ArrayBuffer instantiation");return d(c)})})})().catch(k);return{}})(); +a.___wasm_call_ctors=function(){return(a.___wasm_call_ctors=a.asm.__wasm_call_ctors).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.malloc).apply(null,arguments)};a._free=function(){return(a._free=a.asm.free).apply(null,arguments)};a._spine_enable_debug_extension=function(){return(a._spine_enable_debug_extension=a.asm.spine_enable_debug_extension).apply(null,arguments)};a._spine_major_version=function(){return(a._spine_major_version=a.asm.spine_major_version).apply(null,arguments)}; +a._spine_minor_version=function(){return(a._spine_minor_version=a.asm.spine_minor_version).apply(null,arguments)};a._spine_report_leaks=function(){return(a._spine_report_leaks=a.asm.spine_report_leaks).apply(null,arguments)};a._spine_color_get_r=function(){return(a._spine_color_get_r=a.asm.spine_color_get_r).apply(null,arguments)};a._spine_color_get_g=function(){return(a._spine_color_get_g=a.asm.spine_color_get_g).apply(null,arguments)}; +a._spine_color_get_b=function(){return(a._spine_color_get_b=a.asm.spine_color_get_b).apply(null,arguments)};a._spine_color_get_a=function(){return(a._spine_color_get_a=a.asm.spine_color_get_a).apply(null,arguments)};a._spine_bounds_get_x=function(){return(a._spine_bounds_get_x=a.asm.spine_bounds_get_x).apply(null,arguments)};a._spine_bounds_get_y=function(){return(a._spine_bounds_get_y=a.asm.spine_bounds_get_y).apply(null,arguments)}; +a._spine_bounds_get_width=function(){return(a._spine_bounds_get_width=a.asm.spine_bounds_get_width).apply(null,arguments)};a._spine_bounds_get_height=function(){return(a._spine_bounds_get_height=a.asm.spine_bounds_get_height).apply(null,arguments)};a._spine_vector_get_x=function(){return(a._spine_vector_get_x=a.asm.spine_vector_get_x).apply(null,arguments)};a._spine_vector_get_y=function(){return(a._spine_vector_get_y=a.asm.spine_vector_get_y).apply(null,arguments)}; +a._spine_atlas_load=function(){return(a._spine_atlas_load=a.asm.spine_atlas_load).apply(null,arguments)};a._spine_atlas_get_num_image_paths=function(){return(a._spine_atlas_get_num_image_paths=a.asm.spine_atlas_get_num_image_paths).apply(null,arguments)};a._spine_atlas_get_image_path=function(){return(a._spine_atlas_get_image_path=a.asm.spine_atlas_get_image_path).apply(null,arguments)};a._spine_atlas_get_error=function(){return(a._spine_atlas_get_error=a.asm.spine_atlas_get_error).apply(null,arguments)}; +a._spine_atlas_dispose=function(){return(a._spine_atlas_dispose=a.asm.spine_atlas_dispose).apply(null,arguments)};a._spine_skeleton_data_load_json=function(){return(a._spine_skeleton_data_load_json=a.asm.spine_skeleton_data_load_json).apply(null,arguments)};a._spine_skeleton_data_load_binary=function(){return(a._spine_skeleton_data_load_binary=a.asm.spine_skeleton_data_load_binary).apply(null,arguments)}; +a._spine_skeleton_data_result_get_error=function(){return(a._spine_skeleton_data_result_get_error=a.asm.spine_skeleton_data_result_get_error).apply(null,arguments)};a._spine_skeleton_data_result_get_data=function(){return(a._spine_skeleton_data_result_get_data=a.asm.spine_skeleton_data_result_get_data).apply(null,arguments)};a._spine_skeleton_data_result_dispose=function(){return(a._spine_skeleton_data_result_dispose=a.asm.spine_skeleton_data_result_dispose).apply(null,arguments)}; +a._spine_skeleton_data_find_bone=function(){return(a._spine_skeleton_data_find_bone=a.asm.spine_skeleton_data_find_bone).apply(null,arguments)};a._spine_skeleton_data_find_slot=function(){return(a._spine_skeleton_data_find_slot=a.asm.spine_skeleton_data_find_slot).apply(null,arguments)};a._spine_skeleton_data_find_skin=function(){return(a._spine_skeleton_data_find_skin=a.asm.spine_skeleton_data_find_skin).apply(null,arguments)}; +a._spine_skeleton_data_find_event=function(){return(a._spine_skeleton_data_find_event=a.asm.spine_skeleton_data_find_event).apply(null,arguments)};a._spine_skeleton_data_find_animation=function(){return(a._spine_skeleton_data_find_animation=a.asm.spine_skeleton_data_find_animation).apply(null,arguments)};a._spine_skeleton_data_find_ik_constraint=function(){return(a._spine_skeleton_data_find_ik_constraint=a.asm.spine_skeleton_data_find_ik_constraint).apply(null,arguments)}; +a._spine_skeleton_data_find_transform_constraint=function(){return(a._spine_skeleton_data_find_transform_constraint=a.asm.spine_skeleton_data_find_transform_constraint).apply(null,arguments)};a._spine_skeleton_data_find_path_constraint=function(){return(a._spine_skeleton_data_find_path_constraint=a.asm.spine_skeleton_data_find_path_constraint).apply(null,arguments)};a._spine_skeleton_data_get_name=function(){return(a._spine_skeleton_data_get_name=a.asm.spine_skeleton_data_get_name).apply(null,arguments)}; +a._spine_skeleton_data_get_num_bones=function(){return(a._spine_skeleton_data_get_num_bones=a.asm.spine_skeleton_data_get_num_bones).apply(null,arguments)};a._spine_skeleton_data_get_bones=function(){return(a._spine_skeleton_data_get_bones=a.asm.spine_skeleton_data_get_bones).apply(null,arguments)};a._spine_skeleton_data_get_num_slots=function(){return(a._spine_skeleton_data_get_num_slots=a.asm.spine_skeleton_data_get_num_slots).apply(null,arguments)}; +a._spine_skeleton_data_get_slots=function(){return(a._spine_skeleton_data_get_slots=a.asm.spine_skeleton_data_get_slots).apply(null,arguments)};a._spine_skeleton_data_get_num_skins=function(){return(a._spine_skeleton_data_get_num_skins=a.asm.spine_skeleton_data_get_num_skins).apply(null,arguments)};a._spine_skeleton_data_get_skins=function(){return(a._spine_skeleton_data_get_skins=a.asm.spine_skeleton_data_get_skins).apply(null,arguments)}; +a._spine_skeleton_data_get_default_skin=function(){return(a._spine_skeleton_data_get_default_skin=a.asm.spine_skeleton_data_get_default_skin).apply(null,arguments)};a._spine_skeleton_data_set_default_skin=function(){return(a._spine_skeleton_data_set_default_skin=a.asm.spine_skeleton_data_set_default_skin).apply(null,arguments)};a._spine_skeleton_data_get_num_events=function(){return(a._spine_skeleton_data_get_num_events=a.asm.spine_skeleton_data_get_num_events).apply(null,arguments)}; +a._spine_skeleton_data_get_events=function(){return(a._spine_skeleton_data_get_events=a.asm.spine_skeleton_data_get_events).apply(null,arguments)};a._spine_skeleton_data_get_num_animations=function(){return(a._spine_skeleton_data_get_num_animations=a.asm.spine_skeleton_data_get_num_animations).apply(null,arguments)};a._spine_skeleton_data_get_animations=function(){return(a._spine_skeleton_data_get_animations=a.asm.spine_skeleton_data_get_animations).apply(null,arguments)}; +a._spine_skeleton_data_get_num_ik_constraints=function(){return(a._spine_skeleton_data_get_num_ik_constraints=a.asm.spine_skeleton_data_get_num_ik_constraints).apply(null,arguments)};a._spine_skeleton_data_get_ik_constraints=function(){return(a._spine_skeleton_data_get_ik_constraints=a.asm.spine_skeleton_data_get_ik_constraints).apply(null,arguments)}; +a._spine_skeleton_data_get_num_transform_constraints=function(){return(a._spine_skeleton_data_get_num_transform_constraints=a.asm.spine_skeleton_data_get_num_transform_constraints).apply(null,arguments)};a._spine_skeleton_data_get_transform_constraints=function(){return(a._spine_skeleton_data_get_transform_constraints=a.asm.spine_skeleton_data_get_transform_constraints).apply(null,arguments)}; +a._spine_skeleton_data_get_num_path_constraints=function(){return(a._spine_skeleton_data_get_num_path_constraints=a.asm.spine_skeleton_data_get_num_path_constraints).apply(null,arguments)};a._spine_skeleton_data_get_path_constraints=function(){return(a._spine_skeleton_data_get_path_constraints=a.asm.spine_skeleton_data_get_path_constraints).apply(null,arguments)};a._spine_skeleton_data_get_x=function(){return(a._spine_skeleton_data_get_x=a.asm.spine_skeleton_data_get_x).apply(null,arguments)}; +a._spine_skeleton_data_set_x=function(){return(a._spine_skeleton_data_set_x=a.asm.spine_skeleton_data_set_x).apply(null,arguments)};a._spine_skeleton_data_get_y=function(){return(a._spine_skeleton_data_get_y=a.asm.spine_skeleton_data_get_y).apply(null,arguments)};a._spine_skeleton_data_set_y=function(){return(a._spine_skeleton_data_set_y=a.asm.spine_skeleton_data_set_y).apply(null,arguments)}; +a._spine_skeleton_data_get_width=function(){return(a._spine_skeleton_data_get_width=a.asm.spine_skeleton_data_get_width).apply(null,arguments)};a._spine_skeleton_data_set_width=function(){return(a._spine_skeleton_data_set_width=a.asm.spine_skeleton_data_set_width).apply(null,arguments)};a._spine_skeleton_data_get_height=function(){return(a._spine_skeleton_data_get_height=a.asm.spine_skeleton_data_get_height).apply(null,arguments)}; +a._spine_skeleton_data_set_height=function(){return(a._spine_skeleton_data_set_height=a.asm.spine_skeleton_data_set_height).apply(null,arguments)};a._spine_skeleton_data_get_version=function(){return(a._spine_skeleton_data_get_version=a.asm.spine_skeleton_data_get_version).apply(null,arguments)};a._spine_skeleton_data_get_hash=function(){return(a._spine_skeleton_data_get_hash=a.asm.spine_skeleton_data_get_hash).apply(null,arguments)}; +a._spine_skeleton_data_get_images_path=function(){return(a._spine_skeleton_data_get_images_path=a.asm.spine_skeleton_data_get_images_path).apply(null,arguments)};a._spine_skeleton_data_get_audio_path=function(){return(a._spine_skeleton_data_get_audio_path=a.asm.spine_skeleton_data_get_audio_path).apply(null,arguments)};a._spine_skeleton_data_get_fps=function(){return(a._spine_skeleton_data_get_fps=a.asm.spine_skeleton_data_get_fps).apply(null,arguments)}; +a._spine_skeleton_data_dispose=function(){return(a._spine_skeleton_data_dispose=a.asm.spine_skeleton_data_dispose).apply(null,arguments)};a._spine_skeleton_drawable_create=function(){return(a._spine_skeleton_drawable_create=a.asm.spine_skeleton_drawable_create).apply(null,arguments)};a._spine_skeleton_drawable_dispose=function(){return(a._spine_skeleton_drawable_dispose=a.asm.spine_skeleton_drawable_dispose).apply(null,arguments)}; +a._spine_skeleton_drawable_render=function(){return(a._spine_skeleton_drawable_render=a.asm.spine_skeleton_drawable_render).apply(null,arguments)};a._spine_skeleton_drawable_get_skeleton=function(){return(a._spine_skeleton_drawable_get_skeleton=a.asm.spine_skeleton_drawable_get_skeleton).apply(null,arguments)};a._spine_skeleton_drawable_get_animation_state=function(){return(a._spine_skeleton_drawable_get_animation_state=a.asm.spine_skeleton_drawable_get_animation_state).apply(null,arguments)}; +a._spine_skeleton_drawable_get_animation_state_data=function(){return(a._spine_skeleton_drawable_get_animation_state_data=a.asm.spine_skeleton_drawable_get_animation_state_data).apply(null,arguments)};a._spine_skeleton_drawable_get_animation_state_events=function(){return(a._spine_skeleton_drawable_get_animation_state_events=a.asm.spine_skeleton_drawable_get_animation_state_events).apply(null,arguments)}; +a._spine_render_command_get_positions=function(){return(a._spine_render_command_get_positions=a.asm.spine_render_command_get_positions).apply(null,arguments)};a._spine_render_command_get_uvs=function(){return(a._spine_render_command_get_uvs=a.asm.spine_render_command_get_uvs).apply(null,arguments)};a._spine_render_command_get_colors=function(){return(a._spine_render_command_get_colors=a.asm.spine_render_command_get_colors).apply(null,arguments)}; +a._spine_render_command_get_num_vertices=function(){return(a._spine_render_command_get_num_vertices=a.asm.spine_render_command_get_num_vertices).apply(null,arguments)};a._spine_render_command_get_indices=function(){return(a._spine_render_command_get_indices=a.asm.spine_render_command_get_indices).apply(null,arguments)};a._spine_render_command_get_num_indices=function(){return(a._spine_render_command_get_num_indices=a.asm.spine_render_command_get_num_indices).apply(null,arguments)}; +a._spine_render_command_get_atlas_page=function(){return(a._spine_render_command_get_atlas_page=a.asm.spine_render_command_get_atlas_page).apply(null,arguments)};a._spine_render_command_get_blend_mode=function(){return(a._spine_render_command_get_blend_mode=a.asm.spine_render_command_get_blend_mode).apply(null,arguments)};a._spine_render_command_get_next=function(){return(a._spine_render_command_get_next=a.asm.spine_render_command_get_next).apply(null,arguments)}; +a._spine_animation_get_name=function(){return(a._spine_animation_get_name=a.asm.spine_animation_get_name).apply(null,arguments)};a._spine_animation_get_duration=function(){return(a._spine_animation_get_duration=a.asm.spine_animation_get_duration).apply(null,arguments)};a._spine_animation_state_data_get_skeleton_data=function(){return(a._spine_animation_state_data_get_skeleton_data=a.asm.spine_animation_state_data_get_skeleton_data).apply(null,arguments)}; +a._spine_animation_state_data_get_default_mix=function(){return(a._spine_animation_state_data_get_default_mix=a.asm.spine_animation_state_data_get_default_mix).apply(null,arguments)};a._spine_animation_state_data_set_default_mix=function(){return(a._spine_animation_state_data_set_default_mix=a.asm.spine_animation_state_data_set_default_mix).apply(null,arguments)}; +a._spine_animation_state_data_set_mix=function(){return(a._spine_animation_state_data_set_mix=a.asm.spine_animation_state_data_set_mix).apply(null,arguments)};a._spine_animation_state_data_get_mix=function(){return(a._spine_animation_state_data_get_mix=a.asm.spine_animation_state_data_get_mix).apply(null,arguments)};a._spine_animation_state_data_set_mix_by_name=function(){return(a._spine_animation_state_data_set_mix_by_name=a.asm.spine_animation_state_data_set_mix_by_name).apply(null,arguments)}; +a._spine_animation_state_data_get_mix_by_name=function(){return(a._spine_animation_state_data_get_mix_by_name=a.asm.spine_animation_state_data_get_mix_by_name).apply(null,arguments)};a._spine_animation_state_data_clear=function(){return(a._spine_animation_state_data_clear=a.asm.spine_animation_state_data_clear).apply(null,arguments)};a._spine_animation_state_update=function(){return(a._spine_animation_state_update=a.asm.spine_animation_state_update).apply(null,arguments)}; +a._spine_animation_state_dispose_track_entry=function(){return(a._spine_animation_state_dispose_track_entry=a.asm.spine_animation_state_dispose_track_entry).apply(null,arguments)};a._spine_animation_state_apply=function(){return(a._spine_animation_state_apply=a.asm.spine_animation_state_apply).apply(null,arguments)};a._spine_animation_state_clear_tracks=function(){return(a._spine_animation_state_clear_tracks=a.asm.spine_animation_state_clear_tracks).apply(null,arguments)}; +a._spine_animation_state_get_num_tracks=function(){return(a._spine_animation_state_get_num_tracks=a.asm.spine_animation_state_get_num_tracks).apply(null,arguments)};a._spine_animation_state_clear_track=function(){return(a._spine_animation_state_clear_track=a.asm.spine_animation_state_clear_track).apply(null,arguments)};a._spine_animation_state_set_animation_by_name=function(){return(a._spine_animation_state_set_animation_by_name=a.asm.spine_animation_state_set_animation_by_name).apply(null,arguments)}; +a._spine_animation_state_set_animation=function(){return(a._spine_animation_state_set_animation=a.asm.spine_animation_state_set_animation).apply(null,arguments)};a._spine_animation_state_add_animation_by_name=function(){return(a._spine_animation_state_add_animation_by_name=a.asm.spine_animation_state_add_animation_by_name).apply(null,arguments)};a._spine_animation_state_add_animation=function(){return(a._spine_animation_state_add_animation=a.asm.spine_animation_state_add_animation).apply(null,arguments)}; +a._spine_animation_state_set_empty_animation=function(){return(a._spine_animation_state_set_empty_animation=a.asm.spine_animation_state_set_empty_animation).apply(null,arguments)};a._spine_animation_state_add_empty_animation=function(){return(a._spine_animation_state_add_empty_animation=a.asm.spine_animation_state_add_empty_animation).apply(null,arguments)}; +a._spine_animation_state_set_empty_animations=function(){return(a._spine_animation_state_set_empty_animations=a.asm.spine_animation_state_set_empty_animations).apply(null,arguments)};a._spine_animation_state_get_current=function(){return(a._spine_animation_state_get_current=a.asm.spine_animation_state_get_current).apply(null,arguments)};a._spine_animation_state_get_data=function(){return(a._spine_animation_state_get_data=a.asm.spine_animation_state_get_data).apply(null,arguments)}; +a._spine_animation_state_get_time_scale=function(){return(a._spine_animation_state_get_time_scale=a.asm.spine_animation_state_get_time_scale).apply(null,arguments)};a._spine_animation_state_set_time_scale=function(){return(a._spine_animation_state_set_time_scale=a.asm.spine_animation_state_set_time_scale).apply(null,arguments)}; +a._spine_animation_state_events_get_num_events=function(){return(a._spine_animation_state_events_get_num_events=a.asm.spine_animation_state_events_get_num_events).apply(null,arguments)};a._spine_animation_state_events_get_event_type=function(){return(a._spine_animation_state_events_get_event_type=a.asm.spine_animation_state_events_get_event_type).apply(null,arguments)}; +a._spine_animation_state_events_get_track_entry=function(){return(a._spine_animation_state_events_get_track_entry=a.asm.spine_animation_state_events_get_track_entry).apply(null,arguments)};a._spine_animation_state_events_get_event=function(){return(a._spine_animation_state_events_get_event=a.asm.spine_animation_state_events_get_event).apply(null,arguments)}; +a._spine_animation_state_events_reset=function(){return(a._spine_animation_state_events_reset=a.asm.spine_animation_state_events_reset).apply(null,arguments)};a._spine_track_entry_get_track_index=function(){return(a._spine_track_entry_get_track_index=a.asm.spine_track_entry_get_track_index).apply(null,arguments)};a._spine_track_entry_get_animation=function(){return(a._spine_track_entry_get_animation=a.asm.spine_track_entry_get_animation).apply(null,arguments)}; +a._spine_track_entry_get_previous=function(){return(a._spine_track_entry_get_previous=a.asm.spine_track_entry_get_previous).apply(null,arguments)};a._spine_track_entry_get_loop=function(){return(a._spine_track_entry_get_loop=a.asm.spine_track_entry_get_loop).apply(null,arguments)};a._spine_track_entry_set_loop=function(){return(a._spine_track_entry_set_loop=a.asm.spine_track_entry_set_loop).apply(null,arguments)}; +a._spine_track_entry_get_hold_previous=function(){return(a._spine_track_entry_get_hold_previous=a.asm.spine_track_entry_get_hold_previous).apply(null,arguments)};a._spine_track_entry_set_hold_previous=function(){return(a._spine_track_entry_set_hold_previous=a.asm.spine_track_entry_set_hold_previous).apply(null,arguments)};a._spine_track_entry_get_reverse=function(){return(a._spine_track_entry_get_reverse=a.asm.spine_track_entry_get_reverse).apply(null,arguments)}; +a._spine_track_entry_set_reverse=function(){return(a._spine_track_entry_set_reverse=a.asm.spine_track_entry_set_reverse).apply(null,arguments)};a._spine_track_entry_get_shortest_rotation=function(){return(a._spine_track_entry_get_shortest_rotation=a.asm.spine_track_entry_get_shortest_rotation).apply(null,arguments)};a._spine_track_entry_set_shortest_rotation=function(){return(a._spine_track_entry_set_shortest_rotation=a.asm.spine_track_entry_set_shortest_rotation).apply(null,arguments)}; +a._spine_track_entry_get_delay=function(){return(a._spine_track_entry_get_delay=a.asm.spine_track_entry_get_delay).apply(null,arguments)};a._spine_track_entry_set_delay=function(){return(a._spine_track_entry_set_delay=a.asm.spine_track_entry_set_delay).apply(null,arguments)};a._spine_track_entry_get_track_time=function(){return(a._spine_track_entry_get_track_time=a.asm.spine_track_entry_get_track_time).apply(null,arguments)}; +a._spine_track_entry_set_track_time=function(){return(a._spine_track_entry_set_track_time=a.asm.spine_track_entry_set_track_time).apply(null,arguments)};a._spine_track_entry_get_track_end=function(){return(a._spine_track_entry_get_track_end=a.asm.spine_track_entry_get_track_end).apply(null,arguments)};a._spine_track_entry_set_track_end=function(){return(a._spine_track_entry_set_track_end=a.asm.spine_track_entry_set_track_end).apply(null,arguments)}; +a._spine_track_entry_get_animation_start=function(){return(a._spine_track_entry_get_animation_start=a.asm.spine_track_entry_get_animation_start).apply(null,arguments)};a._spine_track_entry_set_animation_start=function(){return(a._spine_track_entry_set_animation_start=a.asm.spine_track_entry_set_animation_start).apply(null,arguments)};a._spine_track_entry_get_animation_end=function(){return(a._spine_track_entry_get_animation_end=a.asm.spine_track_entry_get_animation_end).apply(null,arguments)}; +a._spine_track_entry_set_animation_end=function(){return(a._spine_track_entry_set_animation_end=a.asm.spine_track_entry_set_animation_end).apply(null,arguments)};a._spine_track_entry_get_animation_last=function(){return(a._spine_track_entry_get_animation_last=a.asm.spine_track_entry_get_animation_last).apply(null,arguments)};a._spine_track_entry_set_animation_last=function(){return(a._spine_track_entry_set_animation_last=a.asm.spine_track_entry_set_animation_last).apply(null,arguments)}; +a._spine_track_entry_get_animation_time=function(){return(a._spine_track_entry_get_animation_time=a.asm.spine_track_entry_get_animation_time).apply(null,arguments)};a._spine_track_entry_get_time_scale=function(){return(a._spine_track_entry_get_time_scale=a.asm.spine_track_entry_get_time_scale).apply(null,arguments)};a._spine_track_entry_set_time_scale=function(){return(a._spine_track_entry_set_time_scale=a.asm.spine_track_entry_set_time_scale).apply(null,arguments)}; +a._spine_track_entry_get_alpha=function(){return(a._spine_track_entry_get_alpha=a.asm.spine_track_entry_get_alpha).apply(null,arguments)};a._spine_track_entry_set_alpha=function(){return(a._spine_track_entry_set_alpha=a.asm.spine_track_entry_set_alpha).apply(null,arguments)};a._spine_track_entry_get_event_threshold=function(){return(a._spine_track_entry_get_event_threshold=a.asm.spine_track_entry_get_event_threshold).apply(null,arguments)}; +a._spine_track_entry_set_event_threshold=function(){return(a._spine_track_entry_set_event_threshold=a.asm.spine_track_entry_set_event_threshold).apply(null,arguments)};a._spine_track_entry_get_attachment_threshold=function(){return(a._spine_track_entry_get_attachment_threshold=a.asm.spine_track_entry_get_attachment_threshold).apply(null,arguments)}; +a._spine_track_entry_set_attachment_threshold=function(){return(a._spine_track_entry_set_attachment_threshold=a.asm.spine_track_entry_set_attachment_threshold).apply(null,arguments)};a._spine_track_entry_get_draw_order_threshold=function(){return(a._spine_track_entry_get_draw_order_threshold=a.asm.spine_track_entry_get_draw_order_threshold).apply(null,arguments)}; +a._spine_track_entry_set_draw_order_threshold=function(){return(a._spine_track_entry_set_draw_order_threshold=a.asm.spine_track_entry_set_draw_order_threshold).apply(null,arguments)};a._spine_track_entry_get_next=function(){return(a._spine_track_entry_get_next=a.asm.spine_track_entry_get_next).apply(null,arguments)};a._spine_track_entry_is_complete=function(){return(a._spine_track_entry_is_complete=a.asm.spine_track_entry_is_complete).apply(null,arguments)}; +a._spine_track_entry_get_mix_time=function(){return(a._spine_track_entry_get_mix_time=a.asm.spine_track_entry_get_mix_time).apply(null,arguments)};a._spine_track_entry_set_mix_time=function(){return(a._spine_track_entry_set_mix_time=a.asm.spine_track_entry_set_mix_time).apply(null,arguments)};a._spine_track_entry_get_mix_duration=function(){return(a._spine_track_entry_get_mix_duration=a.asm.spine_track_entry_get_mix_duration).apply(null,arguments)}; +a._spine_track_entry_set_mix_duration=function(){return(a._spine_track_entry_set_mix_duration=a.asm.spine_track_entry_set_mix_duration).apply(null,arguments)};a._spine_track_entry_get_mix_blend=function(){return(a._spine_track_entry_get_mix_blend=a.asm.spine_track_entry_get_mix_blend).apply(null,arguments)};a._spine_track_entry_set_mix_blend=function(){return(a._spine_track_entry_set_mix_blend=a.asm.spine_track_entry_set_mix_blend).apply(null,arguments)}; +a._spine_track_entry_get_mixing_from=function(){return(a._spine_track_entry_get_mixing_from=a.asm.spine_track_entry_get_mixing_from).apply(null,arguments)};a._spine_track_entry_get_mixing_to=function(){return(a._spine_track_entry_get_mixing_to=a.asm.spine_track_entry_get_mixing_to).apply(null,arguments)};a._spine_track_entry_reset_rotation_directions=function(){return(a._spine_track_entry_reset_rotation_directions=a.asm.spine_track_entry_reset_rotation_directions).apply(null,arguments)}; +a._spine_track_entry_get_track_complete=function(){return(a._spine_track_entry_get_track_complete=a.asm.spine_track_entry_get_track_complete).apply(null,arguments)};a._spine_skeleton_update_cache=function(){return(a._spine_skeleton_update_cache=a.asm.spine_skeleton_update_cache).apply(null,arguments)};a._spine_skeleton_update_world_transform=function(){return(a._spine_skeleton_update_world_transform=a.asm.spine_skeleton_update_world_transform).apply(null,arguments)}; +a._spine_skeleton_update_world_transform_bone=function(){return(a._spine_skeleton_update_world_transform_bone=a.asm.spine_skeleton_update_world_transform_bone).apply(null,arguments)};a._spine_skeleton_set_to_setup_pose=function(){return(a._spine_skeleton_set_to_setup_pose=a.asm.spine_skeleton_set_to_setup_pose).apply(null,arguments)};a._spine_skeleton_set_bones_to_setup_pose=function(){return(a._spine_skeleton_set_bones_to_setup_pose=a.asm.spine_skeleton_set_bones_to_setup_pose).apply(null,arguments)}; +a._spine_skeleton_set_slots_to_setup_pose=function(){return(a._spine_skeleton_set_slots_to_setup_pose=a.asm.spine_skeleton_set_slots_to_setup_pose).apply(null,arguments)};a._spine_skeleton_find_bone=function(){return(a._spine_skeleton_find_bone=a.asm.spine_skeleton_find_bone).apply(null,arguments)};a._spine_skeleton_find_slot=function(){return(a._spine_skeleton_find_slot=a.asm.spine_skeleton_find_slot).apply(null,arguments)}; +a._spine_skeleton_set_skin_by_name=function(){return(a._spine_skeleton_set_skin_by_name=a.asm.spine_skeleton_set_skin_by_name).apply(null,arguments)};a._spine_skeleton_set_skin=function(){return(a._spine_skeleton_set_skin=a.asm.spine_skeleton_set_skin).apply(null,arguments)};a._spine_skeleton_get_attachment_by_name=function(){return(a._spine_skeleton_get_attachment_by_name=a.asm.spine_skeleton_get_attachment_by_name).apply(null,arguments)}; +a._spine_skeleton_get_attachment=function(){return(a._spine_skeleton_get_attachment=a.asm.spine_skeleton_get_attachment).apply(null,arguments)};a._spine_skeleton_set_attachment=function(){return(a._spine_skeleton_set_attachment=a.asm.spine_skeleton_set_attachment).apply(null,arguments)};a._spine_skeleton_find_ik_constraint=function(){return(a._spine_skeleton_find_ik_constraint=a.asm.spine_skeleton_find_ik_constraint).apply(null,arguments)}; +a._spine_skeleton_find_transform_constraint=function(){return(a._spine_skeleton_find_transform_constraint=a.asm.spine_skeleton_find_transform_constraint).apply(null,arguments)};a._spine_skeleton_find_path_constraint=function(){return(a._spine_skeleton_find_path_constraint=a.asm.spine_skeleton_find_path_constraint).apply(null,arguments)};a._spine_skeleton_get_bounds=function(){return(a._spine_skeleton_get_bounds=a.asm.spine_skeleton_get_bounds).apply(null,arguments)}; +a._spine_skeleton_get_root_bone=function(){return(a._spine_skeleton_get_root_bone=a.asm.spine_skeleton_get_root_bone).apply(null,arguments)};a._spine_skeleton_get_data=function(){return(a._spine_skeleton_get_data=a.asm.spine_skeleton_get_data).apply(null,arguments)};a._spine_skeleton_get_num_bones=function(){return(a._spine_skeleton_get_num_bones=a.asm.spine_skeleton_get_num_bones).apply(null,arguments)}; +a._spine_skeleton_get_bones=function(){return(a._spine_skeleton_get_bones=a.asm.spine_skeleton_get_bones).apply(null,arguments)};a._spine_skeleton_get_num_slots=function(){return(a._spine_skeleton_get_num_slots=a.asm.spine_skeleton_get_num_slots).apply(null,arguments)};a._spine_skeleton_get_slots=function(){return(a._spine_skeleton_get_slots=a.asm.spine_skeleton_get_slots).apply(null,arguments)}; +a._spine_skeleton_get_num_draw_order=function(){return(a._spine_skeleton_get_num_draw_order=a.asm.spine_skeleton_get_num_draw_order).apply(null,arguments)};a._spine_skeleton_get_draw_order=function(){return(a._spine_skeleton_get_draw_order=a.asm.spine_skeleton_get_draw_order).apply(null,arguments)};a._spine_skeleton_get_num_ik_constraints=function(){return(a._spine_skeleton_get_num_ik_constraints=a.asm.spine_skeleton_get_num_ik_constraints).apply(null,arguments)}; +a._spine_skeleton_get_ik_constraints=function(){return(a._spine_skeleton_get_ik_constraints=a.asm.spine_skeleton_get_ik_constraints).apply(null,arguments)};a._spine_skeleton_get_num_transform_constraints=function(){return(a._spine_skeleton_get_num_transform_constraints=a.asm.spine_skeleton_get_num_transform_constraints).apply(null,arguments)}; +a._spine_skeleton_get_transform_constraints=function(){return(a._spine_skeleton_get_transform_constraints=a.asm.spine_skeleton_get_transform_constraints).apply(null,arguments)};a._spine_skeleton_get_num_path_constraints=function(){return(a._spine_skeleton_get_num_path_constraints=a.asm.spine_skeleton_get_num_path_constraints).apply(null,arguments)}; +a._spine_skeleton_get_path_constraints=function(){return(a._spine_skeleton_get_path_constraints=a.asm.spine_skeleton_get_path_constraints).apply(null,arguments)};a._spine_skeleton_get_skin=function(){return(a._spine_skeleton_get_skin=a.asm.spine_skeleton_get_skin).apply(null,arguments)};a._spine_skeleton_get_color=function(){return(a._spine_skeleton_get_color=a.asm.spine_skeleton_get_color).apply(null,arguments)}; +a._spine_skeleton_set_color=function(){return(a._spine_skeleton_set_color=a.asm.spine_skeleton_set_color).apply(null,arguments)};a._spine_skeleton_set_position=function(){return(a._spine_skeleton_set_position=a.asm.spine_skeleton_set_position).apply(null,arguments)};a._spine_skeleton_get_x=function(){return(a._spine_skeleton_get_x=a.asm.spine_skeleton_get_x).apply(null,arguments)};a._spine_skeleton_set_x=function(){return(a._spine_skeleton_set_x=a.asm.spine_skeleton_set_x).apply(null,arguments)}; +a._spine_skeleton_get_y=function(){return(a._spine_skeleton_get_y=a.asm.spine_skeleton_get_y).apply(null,arguments)};a._spine_skeleton_set_y=function(){return(a._spine_skeleton_set_y=a.asm.spine_skeleton_set_y).apply(null,arguments)};a._spine_skeleton_get_scale_x=function(){return(a._spine_skeleton_get_scale_x=a.asm.spine_skeleton_get_scale_x).apply(null,arguments)};a._spine_skeleton_set_scale_x=function(){return(a._spine_skeleton_set_scale_x=a.asm.spine_skeleton_set_scale_x).apply(null,arguments)}; +a._spine_skeleton_get_scale_y=function(){return(a._spine_skeleton_get_scale_y=a.asm.spine_skeleton_get_scale_y).apply(null,arguments)};a._spine_skeleton_set_scale_y=function(){return(a._spine_skeleton_set_scale_y=a.asm.spine_skeleton_set_scale_y).apply(null,arguments)};a._spine_event_data_get_name=function(){return(a._spine_event_data_get_name=a.asm.spine_event_data_get_name).apply(null,arguments)}; +a._spine_event_data_get_int_value=function(){return(a._spine_event_data_get_int_value=a.asm.spine_event_data_get_int_value).apply(null,arguments)};a._spine_event_data_set_int_value=function(){return(a._spine_event_data_set_int_value=a.asm.spine_event_data_set_int_value).apply(null,arguments)};a._spine_event_data_get_float_value=function(){return(a._spine_event_data_get_float_value=a.asm.spine_event_data_get_float_value).apply(null,arguments)}; +a._spine_event_data_set_float_value=function(){return(a._spine_event_data_set_float_value=a.asm.spine_event_data_set_float_value).apply(null,arguments)};a._spine_event_data_get_string_value=function(){return(a._spine_event_data_get_string_value=a.asm.spine_event_data_get_string_value).apply(null,arguments)};a._spine_event_data_set_string_value=function(){return(a._spine_event_data_set_string_value=a.asm.spine_event_data_set_string_value).apply(null,arguments)}; +a._spine_event_data_get_audio_path=function(){return(a._spine_event_data_get_audio_path=a.asm.spine_event_data_get_audio_path).apply(null,arguments)};a._spine_event_data_get_volume=function(){return(a._spine_event_data_get_volume=a.asm.spine_event_data_get_volume).apply(null,arguments)};a._spine_event_data_set_volume=function(){return(a._spine_event_data_set_volume=a.asm.spine_event_data_set_volume).apply(null,arguments)}; +a._spine_event_data_get_balance=function(){return(a._spine_event_data_get_balance=a.asm.spine_event_data_get_balance).apply(null,arguments)};a._spine_event_data_set_balance=function(){return(a._spine_event_data_set_balance=a.asm.spine_event_data_set_balance).apply(null,arguments)};a._spine_event_get_data=function(){return(a._spine_event_get_data=a.asm.spine_event_get_data).apply(null,arguments)}; +a._spine_event_get_time=function(){return(a._spine_event_get_time=a.asm.spine_event_get_time).apply(null,arguments)};a._spine_event_get_int_value=function(){return(a._spine_event_get_int_value=a.asm.spine_event_get_int_value).apply(null,arguments)};a._spine_event_set_int_value=function(){return(a._spine_event_set_int_value=a.asm.spine_event_set_int_value).apply(null,arguments)}; +a._spine_event_get_float_value=function(){return(a._spine_event_get_float_value=a.asm.spine_event_get_float_value).apply(null,arguments)};a._spine_event_set_float_value=function(){return(a._spine_event_set_float_value=a.asm.spine_event_set_float_value).apply(null,arguments)};a._spine_event_get_string_value=function(){return(a._spine_event_get_string_value=a.asm.spine_event_get_string_value).apply(null,arguments)}; +a._spine_event_set_string_value=function(){return(a._spine_event_set_string_value=a.asm.spine_event_set_string_value).apply(null,arguments)};a._spine_event_get_volume=function(){return(a._spine_event_get_volume=a.asm.spine_event_get_volume).apply(null,arguments)};a._spine_event_set_volume=function(){return(a._spine_event_set_volume=a.asm.spine_event_set_volume).apply(null,arguments)}; +a._spine_event_get_balance=function(){return(a._spine_event_get_balance=a.asm.spine_event_get_balance).apply(null,arguments)};a._spine_event_set_balance=function(){return(a._spine_event_set_balance=a.asm.spine_event_set_balance).apply(null,arguments)};a._spine_slot_data_get_index=function(){return(a._spine_slot_data_get_index=a.asm.spine_slot_data_get_index).apply(null,arguments)}; +a._spine_slot_data_get_name=function(){return(a._spine_slot_data_get_name=a.asm.spine_slot_data_get_name).apply(null,arguments)};a._spine_slot_data_get_bone_data=function(){return(a._spine_slot_data_get_bone_data=a.asm.spine_slot_data_get_bone_data).apply(null,arguments)};a._spine_slot_data_get_color=function(){return(a._spine_slot_data_get_color=a.asm.spine_slot_data_get_color).apply(null,arguments)}; +a._spine_slot_data_set_color=function(){return(a._spine_slot_data_set_color=a.asm.spine_slot_data_set_color).apply(null,arguments)};a._spine_slot_data_get_dark_color=function(){return(a._spine_slot_data_get_dark_color=a.asm.spine_slot_data_get_dark_color).apply(null,arguments)};a._spine_slot_data_set_dark_color=function(){return(a._spine_slot_data_set_dark_color=a.asm.spine_slot_data_set_dark_color).apply(null,arguments)}; +a._spine_slot_data_has_dark_color=function(){return(a._spine_slot_data_has_dark_color=a.asm.spine_slot_data_has_dark_color).apply(null,arguments)};a._spine_slot_data_set_has_dark_color=function(){return(a._spine_slot_data_set_has_dark_color=a.asm.spine_slot_data_set_has_dark_color).apply(null,arguments)};a._spine_slot_data_get_attachment_name=function(){return(a._spine_slot_data_get_attachment_name=a.asm.spine_slot_data_get_attachment_name).apply(null,arguments)}; +a._spine_slot_data_set_attachment_name=function(){return(a._spine_slot_data_set_attachment_name=a.asm.spine_slot_data_set_attachment_name).apply(null,arguments)};a._spine_slot_data_get_blend_mode=function(){return(a._spine_slot_data_get_blend_mode=a.asm.spine_slot_data_get_blend_mode).apply(null,arguments)};a._spine_slot_set_to_setup_pose=function(){return(a._spine_slot_set_to_setup_pose=a.asm.spine_slot_set_to_setup_pose).apply(null,arguments)}; +a._spine_slot_get_data=function(){return(a._spine_slot_get_data=a.asm.spine_slot_get_data).apply(null,arguments)};a._spine_slot_get_bone=function(){return(a._spine_slot_get_bone=a.asm.spine_slot_get_bone).apply(null,arguments)};a._spine_slot_get_skeleton=function(){return(a._spine_slot_get_skeleton=a.asm.spine_slot_get_skeleton).apply(null,arguments)};a._spine_slot_get_color=function(){return(a._spine_slot_get_color=a.asm.spine_slot_get_color).apply(null,arguments)}; +a._spine_slot_set_color=function(){return(a._spine_slot_set_color=a.asm.spine_slot_set_color).apply(null,arguments)};a._spine_slot_get_dark_color=function(){return(a._spine_slot_get_dark_color=a.asm.spine_slot_get_dark_color).apply(null,arguments)};a._spine_slot_set_dark_color=function(){return(a._spine_slot_set_dark_color=a.asm.spine_slot_set_dark_color).apply(null,arguments)}; +a._spine_slot_has_dark_color=function(){return(a._spine_slot_has_dark_color=a.asm.spine_slot_has_dark_color).apply(null,arguments)};a._spine_slot_get_attachment=function(){return(a._spine_slot_get_attachment=a.asm.spine_slot_get_attachment).apply(null,arguments)};a._spine_slot_set_attachment=function(){return(a._spine_slot_set_attachment=a.asm.spine_slot_set_attachment).apply(null,arguments)}; +a._spine_slot_get_sequence_index=function(){return(a._spine_slot_get_sequence_index=a.asm.spine_slot_get_sequence_index).apply(null,arguments)};a._spine_slot_set_sequence_index=function(){return(a._spine_slot_set_sequence_index=a.asm.spine_slot_set_sequence_index).apply(null,arguments)};a._spine_bone_data_get_index=function(){return(a._spine_bone_data_get_index=a.asm.spine_bone_data_get_index).apply(null,arguments)}; +a._spine_bone_data_get_name=function(){return(a._spine_bone_data_get_name=a.asm.spine_bone_data_get_name).apply(null,arguments)};a._spine_bone_data_get_parent=function(){return(a._spine_bone_data_get_parent=a.asm.spine_bone_data_get_parent).apply(null,arguments)};a._spine_bone_data_get_length=function(){return(a._spine_bone_data_get_length=a.asm.spine_bone_data_get_length).apply(null,arguments)}; +a._spine_bone_data_set_length=function(){return(a._spine_bone_data_set_length=a.asm.spine_bone_data_set_length).apply(null,arguments)};a._spine_bone_data_get_x=function(){return(a._spine_bone_data_get_x=a.asm.spine_bone_data_get_x).apply(null,arguments)};a._spine_bone_data_set_x=function(){return(a._spine_bone_data_set_x=a.asm.spine_bone_data_set_x).apply(null,arguments)};a._spine_bone_data_get_y=function(){return(a._spine_bone_data_get_y=a.asm.spine_bone_data_get_y).apply(null,arguments)}; +a._spine_bone_data_set_y=function(){return(a._spine_bone_data_set_y=a.asm.spine_bone_data_set_y).apply(null,arguments)};a._spine_bone_data_get_rotation=function(){return(a._spine_bone_data_get_rotation=a.asm.spine_bone_data_get_rotation).apply(null,arguments)};a._spine_bone_data_set_rotation=function(){return(a._spine_bone_data_set_rotation=a.asm.spine_bone_data_set_rotation).apply(null,arguments)}; +a._spine_bone_data_get_scale_x=function(){return(a._spine_bone_data_get_scale_x=a.asm.spine_bone_data_get_scale_x).apply(null,arguments)};a._spine_bone_data_set_scale_x=function(){return(a._spine_bone_data_set_scale_x=a.asm.spine_bone_data_set_scale_x).apply(null,arguments)};a._spine_bone_data_get_scale_y=function(){return(a._spine_bone_data_get_scale_y=a.asm.spine_bone_data_get_scale_y).apply(null,arguments)}; +a._spine_bone_data_set_scale_y=function(){return(a._spine_bone_data_set_scale_y=a.asm.spine_bone_data_set_scale_y).apply(null,arguments)};a._spine_bone_data_get_shear_x=function(){return(a._spine_bone_data_get_shear_x=a.asm.spine_bone_data_get_shear_x).apply(null,arguments)};a._spine_bone_data_set_shear_x=function(){return(a._spine_bone_data_set_shear_x=a.asm.spine_bone_data_set_shear_x).apply(null,arguments)}; +a._spine_bone_data_get_shear_y=function(){return(a._spine_bone_data_get_shear_y=a.asm.spine_bone_data_get_shear_y).apply(null,arguments)};a._spine_bone_data_set_shear_y=function(){return(a._spine_bone_data_set_shear_y=a.asm.spine_bone_data_set_shear_y).apply(null,arguments)};a._spine_bone_data_get_transform_mode=function(){return(a._spine_bone_data_get_transform_mode=a.asm.spine_bone_data_get_transform_mode).apply(null,arguments)}; +a._spine_bone_data_set_transform_mode=function(){return(a._spine_bone_data_set_transform_mode=a.asm.spine_bone_data_set_transform_mode).apply(null,arguments)};a._spine_bone_data_is_skin_required=function(){return(a._spine_bone_data_is_skin_required=a.asm.spine_bone_data_is_skin_required).apply(null,arguments)};a._spine_bone_data_set_is_skin_required=function(){return(a._spine_bone_data_set_is_skin_required=a.asm.spine_bone_data_set_is_skin_required).apply(null,arguments)}; +a._spine_bone_data_get_color=function(){return(a._spine_bone_data_get_color=a.asm.spine_bone_data_get_color).apply(null,arguments)};a._spine_bone_data_set_color=function(){return(a._spine_bone_data_set_color=a.asm.spine_bone_data_set_color).apply(null,arguments)};a._spine_bone_set_is_y_down=function(){return(a._spine_bone_set_is_y_down=a.asm.spine_bone_set_is_y_down).apply(null,arguments)}; +a._spine_bone_get_is_y_down=function(){return(a._spine_bone_get_is_y_down=a.asm.spine_bone_get_is_y_down).apply(null,arguments)};a._spine_bone_update=function(){return(a._spine_bone_update=a.asm.spine_bone_update).apply(null,arguments)};a._spine_bone_update_world_transform=function(){return(a._spine_bone_update_world_transform=a.asm.spine_bone_update_world_transform).apply(null,arguments)}; +a._spine_bone_update_world_transform_with=function(){return(a._spine_bone_update_world_transform_with=a.asm.spine_bone_update_world_transform_with).apply(null,arguments)};a._spine_bone_set_to_setup_pose=function(){return(a._spine_bone_set_to_setup_pose=a.asm.spine_bone_set_to_setup_pose).apply(null,arguments)};a._spine_bone_world_to_local=function(){return(a._spine_bone_world_to_local=a.asm.spine_bone_world_to_local).apply(null,arguments)}; +a._spine_bone_local_to_world=function(){return(a._spine_bone_local_to_world=a.asm.spine_bone_local_to_world).apply(null,arguments)};a._spine_bone_world_to_local_rotation=function(){return(a._spine_bone_world_to_local_rotation=a.asm.spine_bone_world_to_local_rotation).apply(null,arguments)};a._spine_bone_local_to_world_rotation=function(){return(a._spine_bone_local_to_world_rotation=a.asm.spine_bone_local_to_world_rotation).apply(null,arguments)}; +a._spine_bone_rotate_world=function(){return(a._spine_bone_rotate_world=a.asm.spine_bone_rotate_world).apply(null,arguments)};a._spine_bone_get_world_to_local_rotation_x=function(){return(a._spine_bone_get_world_to_local_rotation_x=a.asm.spine_bone_get_world_to_local_rotation_x).apply(null,arguments)};a._spine_bone_get_world_to_local_rotation_y=function(){return(a._spine_bone_get_world_to_local_rotation_y=a.asm.spine_bone_get_world_to_local_rotation_y).apply(null,arguments)}; +a._spine_bone_get_data=function(){return(a._spine_bone_get_data=a.asm.spine_bone_get_data).apply(null,arguments)};a._spine_bone_get_skeleton=function(){return(a._spine_bone_get_skeleton=a.asm.spine_bone_get_skeleton).apply(null,arguments)};a._spine_bone_get_parent=function(){return(a._spine_bone_get_parent=a.asm.spine_bone_get_parent).apply(null,arguments)};a._spine_bone_get_num_children=function(){return(a._spine_bone_get_num_children=a.asm.spine_bone_get_num_children).apply(null,arguments)}; +a._spine_bone_get_children=function(){return(a._spine_bone_get_children=a.asm.spine_bone_get_children).apply(null,arguments)};a._spine_bone_get_x=function(){return(a._spine_bone_get_x=a.asm.spine_bone_get_x).apply(null,arguments)};a._spine_bone_set_x=function(){return(a._spine_bone_set_x=a.asm.spine_bone_set_x).apply(null,arguments)};a._spine_bone_get_y=function(){return(a._spine_bone_get_y=a.asm.spine_bone_get_y).apply(null,arguments)}; +a._spine_bone_set_y=function(){return(a._spine_bone_set_y=a.asm.spine_bone_set_y).apply(null,arguments)};a._spine_bone_get_rotation=function(){return(a._spine_bone_get_rotation=a.asm.spine_bone_get_rotation).apply(null,arguments)};a._spine_bone_set_rotation=function(){return(a._spine_bone_set_rotation=a.asm.spine_bone_set_rotation).apply(null,arguments)};a._spine_bone_get_scale_x=function(){return(a._spine_bone_get_scale_x=a.asm.spine_bone_get_scale_x).apply(null,arguments)}; +a._spine_bone_set_scale_x=function(){return(a._spine_bone_set_scale_x=a.asm.spine_bone_set_scale_x).apply(null,arguments)};a._spine_bone_get_scale_y=function(){return(a._spine_bone_get_scale_y=a.asm.spine_bone_get_scale_y).apply(null,arguments)};a._spine_bone_set_scale_y=function(){return(a._spine_bone_set_scale_y=a.asm.spine_bone_set_scale_y).apply(null,arguments)};a._spine_bone_get_shear_x=function(){return(a._spine_bone_get_shear_x=a.asm.spine_bone_get_shear_x).apply(null,arguments)}; +a._spine_bone_set_shear_x=function(){return(a._spine_bone_set_shear_x=a.asm.spine_bone_set_shear_x).apply(null,arguments)};a._spine_bone_get_shear_y=function(){return(a._spine_bone_get_shear_y=a.asm.spine_bone_get_shear_y).apply(null,arguments)};a._spine_bone_set_shear_y=function(){return(a._spine_bone_set_shear_y=a.asm.spine_bone_set_shear_y).apply(null,arguments)}; +a._spine_bone_get_applied_rotation=function(){return(a._spine_bone_get_applied_rotation=a.asm.spine_bone_get_applied_rotation).apply(null,arguments)};a._spine_bone_set_applied_rotation=function(){return(a._spine_bone_set_applied_rotation=a.asm.spine_bone_set_applied_rotation).apply(null,arguments)};a._spine_bone_get_a_x=function(){return(a._spine_bone_get_a_x=a.asm.spine_bone_get_a_x).apply(null,arguments)}; +a._spine_bone_set_a_x=function(){return(a._spine_bone_set_a_x=a.asm.spine_bone_set_a_x).apply(null,arguments)};a._spine_bone_get_a_y=function(){return(a._spine_bone_get_a_y=a.asm.spine_bone_get_a_y).apply(null,arguments)};a._spine_bone_set_a_y=function(){return(a._spine_bone_set_a_y=a.asm.spine_bone_set_a_y).apply(null,arguments)};a._spine_bone_get_a_scale_x=function(){return(a._spine_bone_get_a_scale_x=a.asm.spine_bone_get_a_scale_x).apply(null,arguments)}; +a._spine_bone_set_a_scale_x=function(){return(a._spine_bone_set_a_scale_x=a.asm.spine_bone_set_a_scale_x).apply(null,arguments)};a._spine_bone_get_a_scale_y=function(){return(a._spine_bone_get_a_scale_y=a.asm.spine_bone_get_a_scale_y).apply(null,arguments)};a._spine_bone_set_a_scale_y=function(){return(a._spine_bone_set_a_scale_y=a.asm.spine_bone_set_a_scale_y).apply(null,arguments)}; +a._spine_bone_get_a_shear_x=function(){return(a._spine_bone_get_a_shear_x=a.asm.spine_bone_get_a_shear_x).apply(null,arguments)};a._spine_bone_set_a_shear_x=function(){return(a._spine_bone_set_a_shear_x=a.asm.spine_bone_set_a_shear_x).apply(null,arguments)};a._spine_bone_get_a_shear_y=function(){return(a._spine_bone_get_a_shear_y=a.asm.spine_bone_get_a_shear_y).apply(null,arguments)};a._spine_bone_get_a=function(){return(a._spine_bone_get_a=a.asm.spine_bone_get_a).apply(null,arguments)}; +a._spine_bone_set_a=function(){return(a._spine_bone_set_a=a.asm.spine_bone_set_a).apply(null,arguments)};a._spine_bone_get_b=function(){return(a._spine_bone_get_b=a.asm.spine_bone_get_b).apply(null,arguments)};a._spine_bone_set_b=function(){return(a._spine_bone_set_b=a.asm.spine_bone_set_b).apply(null,arguments)};a._spine_bone_get_c=function(){return(a._spine_bone_get_c=a.asm.spine_bone_get_c).apply(null,arguments)}; +a._spine_bone_set_c=function(){return(a._spine_bone_set_c=a.asm.spine_bone_set_c).apply(null,arguments)};a._spine_bone_get_d=function(){return(a._spine_bone_get_d=a.asm.spine_bone_get_d).apply(null,arguments)};a._spine_bone_set_d=function(){return(a._spine_bone_set_d=a.asm.spine_bone_set_d).apply(null,arguments)};a._spine_bone_get_world_x=function(){return(a._spine_bone_get_world_x=a.asm.spine_bone_get_world_x).apply(null,arguments)}; +a._spine_bone_set_world_x=function(){return(a._spine_bone_set_world_x=a.asm.spine_bone_set_world_x).apply(null,arguments)};a._spine_bone_get_world_y=function(){return(a._spine_bone_get_world_y=a.asm.spine_bone_get_world_y).apply(null,arguments)};a._spine_bone_set_world_y=function(){return(a._spine_bone_set_world_y=a.asm.spine_bone_set_world_y).apply(null,arguments)}; +a._spine_bone_get_world_rotation_x=function(){return(a._spine_bone_get_world_rotation_x=a.asm.spine_bone_get_world_rotation_x).apply(null,arguments)};a._spine_bone_get_world_rotation_y=function(){return(a._spine_bone_get_world_rotation_y=a.asm.spine_bone_get_world_rotation_y).apply(null,arguments)};a._spine_bone_get_world_scale_x=function(){return(a._spine_bone_get_world_scale_x=a.asm.spine_bone_get_world_scale_x).apply(null,arguments)}; +a._spine_bone_get_world_scale_y=function(){return(a._spine_bone_get_world_scale_y=a.asm.spine_bone_get_world_scale_y).apply(null,arguments)};a._spine_bone_get_is_active=function(){return(a._spine_bone_get_is_active=a.asm.spine_bone_get_is_active).apply(null,arguments)};a._spine_bone_set_is_active=function(){return(a._spine_bone_set_is_active=a.asm.spine_bone_set_is_active).apply(null,arguments)}; +a._spine_attachment_get_name=function(){return(a._spine_attachment_get_name=a.asm.spine_attachment_get_name).apply(null,arguments)};a._spine_attachment_get_type=function(){return(a._spine_attachment_get_type=a.asm.spine_attachment_get_type).apply(null,arguments)};a._spine_attachment_copy=function(){return(a._spine_attachment_copy=a.asm.spine_attachment_copy).apply(null,arguments)}; +a._spine_attachment_dispose=function(){return(a._spine_attachment_dispose=a.asm.spine_attachment_dispose).apply(null,arguments)};a._spine_point_attachment_compute_world_position=function(){return(a._spine_point_attachment_compute_world_position=a.asm.spine_point_attachment_compute_world_position).apply(null,arguments)}; +a._spine_point_attachment_compute_world_rotation=function(){return(a._spine_point_attachment_compute_world_rotation=a.asm.spine_point_attachment_compute_world_rotation).apply(null,arguments)};a._spine_point_attachment_get_x=function(){return(a._spine_point_attachment_get_x=a.asm.spine_point_attachment_get_x).apply(null,arguments)};a._spine_point_attachment_set_x=function(){return(a._spine_point_attachment_set_x=a.asm.spine_point_attachment_set_x).apply(null,arguments)}; +a._spine_point_attachment_get_y=function(){return(a._spine_point_attachment_get_y=a.asm.spine_point_attachment_get_y).apply(null,arguments)};a._spine_point_attachment_set_y=function(){return(a._spine_point_attachment_set_y=a.asm.spine_point_attachment_set_y).apply(null,arguments)};a._spine_point_attachment_get_rotation=function(){return(a._spine_point_attachment_get_rotation=a.asm.spine_point_attachment_get_rotation).apply(null,arguments)}; +a._spine_point_attachment_set_rotation=function(){return(a._spine_point_attachment_set_rotation=a.asm.spine_point_attachment_set_rotation).apply(null,arguments)};a._spine_point_attachment_get_color=function(){return(a._spine_point_attachment_get_color=a.asm.spine_point_attachment_get_color).apply(null,arguments)};a._spine_point_attachment_set_color=function(){return(a._spine_point_attachment_set_color=a.asm.spine_point_attachment_set_color).apply(null,arguments)}; +a._spine_region_attachment_update_region=function(){return(a._spine_region_attachment_update_region=a.asm.spine_region_attachment_update_region).apply(null,arguments)};a._spine_region_attachment_compute_world_vertices=function(){return(a._spine_region_attachment_compute_world_vertices=a.asm.spine_region_attachment_compute_world_vertices).apply(null,arguments)};a._spine_region_attachment_get_x=function(){return(a._spine_region_attachment_get_x=a.asm.spine_region_attachment_get_x).apply(null,arguments)}; +a._spine_region_attachment_set_x=function(){return(a._spine_region_attachment_set_x=a.asm.spine_region_attachment_set_x).apply(null,arguments)};a._spine_region_attachment_get_y=function(){return(a._spine_region_attachment_get_y=a.asm.spine_region_attachment_get_y).apply(null,arguments)};a._spine_region_attachment_set_y=function(){return(a._spine_region_attachment_set_y=a.asm.spine_region_attachment_set_y).apply(null,arguments)}; +a._spine_region_attachment_get_rotation=function(){return(a._spine_region_attachment_get_rotation=a.asm.spine_region_attachment_get_rotation).apply(null,arguments)};a._spine_region_attachment_set_rotation=function(){return(a._spine_region_attachment_set_rotation=a.asm.spine_region_attachment_set_rotation).apply(null,arguments)};a._spine_region_attachment_get_scale_x=function(){return(a._spine_region_attachment_get_scale_x=a.asm.spine_region_attachment_get_scale_x).apply(null,arguments)}; +a._spine_region_attachment_set_scale_x=function(){return(a._spine_region_attachment_set_scale_x=a.asm.spine_region_attachment_set_scale_x).apply(null,arguments)};a._spine_region_attachment_get_scale_y=function(){return(a._spine_region_attachment_get_scale_y=a.asm.spine_region_attachment_get_scale_y).apply(null,arguments)};a._spine_region_attachment_set_scale_y=function(){return(a._spine_region_attachment_set_scale_y=a.asm.spine_region_attachment_set_scale_y).apply(null,arguments)}; +a._spine_region_attachment_get_width=function(){return(a._spine_region_attachment_get_width=a.asm.spine_region_attachment_get_width).apply(null,arguments)};a._spine_region_attachment_set_width=function(){return(a._spine_region_attachment_set_width=a.asm.spine_region_attachment_set_width).apply(null,arguments)};a._spine_region_attachment_get_height=function(){return(a._spine_region_attachment_get_height=a.asm.spine_region_attachment_get_height).apply(null,arguments)}; +a._spine_region_attachment_set_height=function(){return(a._spine_region_attachment_set_height=a.asm.spine_region_attachment_set_height).apply(null,arguments)};a._spine_region_attachment_get_color=function(){return(a._spine_region_attachment_get_color=a.asm.spine_region_attachment_get_color).apply(null,arguments)};a._spine_region_attachment_set_color=function(){return(a._spine_region_attachment_set_color=a.asm.spine_region_attachment_set_color).apply(null,arguments)}; +a._spine_region_attachment_get_path=function(){return(a._spine_region_attachment_get_path=a.asm.spine_region_attachment_get_path).apply(null,arguments)};a._spine_region_attachment_get_region=function(){return(a._spine_region_attachment_get_region=a.asm.spine_region_attachment_get_region).apply(null,arguments)};a._spine_region_attachment_get_sequence=function(){return(a._spine_region_attachment_get_sequence=a.asm.spine_region_attachment_get_sequence).apply(null,arguments)}; +a._spine_region_attachment_get_num_offset=function(){return(a._spine_region_attachment_get_num_offset=a.asm.spine_region_attachment_get_num_offset).apply(null,arguments)};a._spine_region_attachment_get_offset=function(){return(a._spine_region_attachment_get_offset=a.asm.spine_region_attachment_get_offset).apply(null,arguments)};a._spine_region_attachment_get_num_uvs=function(){return(a._spine_region_attachment_get_num_uvs=a.asm.spine_region_attachment_get_num_uvs).apply(null,arguments)}; +a._spine_region_attachment_get_uvs=function(){return(a._spine_region_attachment_get_uvs=a.asm.spine_region_attachment_get_uvs).apply(null,arguments)};a._spine_vertex_attachment_get_world_vertices_length=function(){return(a._spine_vertex_attachment_get_world_vertices_length=a.asm.spine_vertex_attachment_get_world_vertices_length).apply(null,arguments)}; +a._spine_vertex_attachment_compute_world_vertices=function(){return(a._spine_vertex_attachment_compute_world_vertices=a.asm.spine_vertex_attachment_compute_world_vertices).apply(null,arguments)};a._spine_vertex_attachment_get_num_bones=function(){return(a._spine_vertex_attachment_get_num_bones=a.asm.spine_vertex_attachment_get_num_bones).apply(null,arguments)}; +a._spine_vertex_attachment_get_bones=function(){return(a._spine_vertex_attachment_get_bones=a.asm.spine_vertex_attachment_get_bones).apply(null,arguments)};a._spine_vertex_attachment_get_num_vertices=function(){return(a._spine_vertex_attachment_get_num_vertices=a.asm.spine_vertex_attachment_get_num_vertices).apply(null,arguments)};a._spine_vertex_attachment_get_vertices=function(){return(a._spine_vertex_attachment_get_vertices=a.asm.spine_vertex_attachment_get_vertices).apply(null,arguments)}; +a._spine_vertex_attachment_get_timeline_attachment=function(){return(a._spine_vertex_attachment_get_timeline_attachment=a.asm.spine_vertex_attachment_get_timeline_attachment).apply(null,arguments)};a._spine_vertex_attachment_set_timeline_attachment=function(){return(a._spine_vertex_attachment_set_timeline_attachment=a.asm.spine_vertex_attachment_set_timeline_attachment).apply(null,arguments)}; +a._spine_mesh_attachment_update_region=function(){return(a._spine_mesh_attachment_update_region=a.asm.spine_mesh_attachment_update_region).apply(null,arguments)};a._spine_mesh_attachment_get_hull_length=function(){return(a._spine_mesh_attachment_get_hull_length=a.asm.spine_mesh_attachment_get_hull_length).apply(null,arguments)};a._spine_mesh_attachment_set_hull_length=function(){return(a._spine_mesh_attachment_set_hull_length=a.asm.spine_mesh_attachment_set_hull_length).apply(null,arguments)}; +a._spine_mesh_attachment_get_num_region_uvs=function(){return(a._spine_mesh_attachment_get_num_region_uvs=a.asm.spine_mesh_attachment_get_num_region_uvs).apply(null,arguments)};a._spine_mesh_attachment_get_region_uvs=function(){return(a._spine_mesh_attachment_get_region_uvs=a.asm.spine_mesh_attachment_get_region_uvs).apply(null,arguments)};a._spine_mesh_attachment_get_num_uvs=function(){return(a._spine_mesh_attachment_get_num_uvs=a.asm.spine_mesh_attachment_get_num_uvs).apply(null,arguments)}; +a._spine_mesh_attachment_get_uvs=function(){return(a._spine_mesh_attachment_get_uvs=a.asm.spine_mesh_attachment_get_uvs).apply(null,arguments)};a._spine_mesh_attachment_get_num_triangles=function(){return(a._spine_mesh_attachment_get_num_triangles=a.asm.spine_mesh_attachment_get_num_triangles).apply(null,arguments)};a._spine_mesh_attachment_get_triangles=function(){return(a._spine_mesh_attachment_get_triangles=a.asm.spine_mesh_attachment_get_triangles).apply(null,arguments)}; +a._spine_mesh_attachment_get_color=function(){return(a._spine_mesh_attachment_get_color=a.asm.spine_mesh_attachment_get_color).apply(null,arguments)};a._spine_mesh_attachment_set_color=function(){return(a._spine_mesh_attachment_set_color=a.asm.spine_mesh_attachment_set_color).apply(null,arguments)};a._spine_mesh_attachment_get_path=function(){return(a._spine_mesh_attachment_get_path=a.asm.spine_mesh_attachment_get_path).apply(null,arguments)}; +a._spine_mesh_attachment_get_region=function(){return(a._spine_mesh_attachment_get_region=a.asm.spine_mesh_attachment_get_region).apply(null,arguments)};a._spine_mesh_attachment_get_sequence=function(){return(a._spine_mesh_attachment_get_sequence=a.asm.spine_mesh_attachment_get_sequence).apply(null,arguments)};a._spine_mesh_attachment_get_parent_mesh=function(){return(a._spine_mesh_attachment_get_parent_mesh=a.asm.spine_mesh_attachment_get_parent_mesh).apply(null,arguments)}; +a._spine_mesh_attachment_set_parent_mesh=function(){return(a._spine_mesh_attachment_set_parent_mesh=a.asm.spine_mesh_attachment_set_parent_mesh).apply(null,arguments)};a._spine_mesh_attachment_get_num_edges=function(){return(a._spine_mesh_attachment_get_num_edges=a.asm.spine_mesh_attachment_get_num_edges).apply(null,arguments)};a._spine_mesh_attachment_get_edges=function(){return(a._spine_mesh_attachment_get_edges=a.asm.spine_mesh_attachment_get_edges).apply(null,arguments)}; +a._spine_mesh_attachment_get_width=function(){return(a._spine_mesh_attachment_get_width=a.asm.spine_mesh_attachment_get_width).apply(null,arguments)};a._spine_mesh_attachment_set_width=function(){return(a._spine_mesh_attachment_set_width=a.asm.spine_mesh_attachment_set_width).apply(null,arguments)};a._spine_mesh_attachment_get_height=function(){return(a._spine_mesh_attachment_get_height=a.asm.spine_mesh_attachment_get_height).apply(null,arguments)}; +a._spine_mesh_attachment_set_height=function(){return(a._spine_mesh_attachment_set_height=a.asm.spine_mesh_attachment_set_height).apply(null,arguments)};a._spine_clipping_attachment_get_end_slot=function(){return(a._spine_clipping_attachment_get_end_slot=a.asm.spine_clipping_attachment_get_end_slot).apply(null,arguments)};a._spine_clipping_attachment_set_end_slot=function(){return(a._spine_clipping_attachment_set_end_slot=a.asm.spine_clipping_attachment_set_end_slot).apply(null,arguments)}; +a._spine_clipping_attachment_get_color=function(){return(a._spine_clipping_attachment_get_color=a.asm.spine_clipping_attachment_get_color).apply(null,arguments)};a._spine_clipping_attachment_set_color=function(){return(a._spine_clipping_attachment_set_color=a.asm.spine_clipping_attachment_set_color).apply(null,arguments)};a._spine_bounding_box_attachment_get_color=function(){return(a._spine_bounding_box_attachment_get_color=a.asm.spine_bounding_box_attachment_get_color).apply(null,arguments)}; +a._spine_bounding_box_attachment_set_color=function(){return(a._spine_bounding_box_attachment_set_color=a.asm.spine_bounding_box_attachment_set_color).apply(null,arguments)};a._spine_path_attachment_get_num_lengths=function(){return(a._spine_path_attachment_get_num_lengths=a.asm.spine_path_attachment_get_num_lengths).apply(null,arguments)};a._spine_path_attachment_get_lengths=function(){return(a._spine_path_attachment_get_lengths=a.asm.spine_path_attachment_get_lengths).apply(null,arguments)}; +a._spine_path_attachment_get_is_closed=function(){return(a._spine_path_attachment_get_is_closed=a.asm.spine_path_attachment_get_is_closed).apply(null,arguments)};a._spine_path_attachment_set_is_closed=function(){return(a._spine_path_attachment_set_is_closed=a.asm.spine_path_attachment_set_is_closed).apply(null,arguments)};a._spine_path_attachment_get_is_constant_speed=function(){return(a._spine_path_attachment_get_is_constant_speed=a.asm.spine_path_attachment_get_is_constant_speed).apply(null,arguments)}; +a._spine_path_attachment_set_is_constant_speed=function(){return(a._spine_path_attachment_set_is_constant_speed=a.asm.spine_path_attachment_set_is_constant_speed).apply(null,arguments)};a._spine_path_attachment_get_color=function(){return(a._spine_path_attachment_get_color=a.asm.spine_path_attachment_get_color).apply(null,arguments)};a._spine_path_attachment_set_color=function(){return(a._spine_path_attachment_set_color=a.asm.spine_path_attachment_set_color).apply(null,arguments)}; +a._spine_skin_set_attachment=function(){return(a._spine_skin_set_attachment=a.asm.spine_skin_set_attachment).apply(null,arguments)};a._spine_skin_get_attachment=function(){return(a._spine_skin_get_attachment=a.asm.spine_skin_get_attachment).apply(null,arguments)};a._spine_skin_remove_attachment=function(){return(a._spine_skin_remove_attachment=a.asm.spine_skin_remove_attachment).apply(null,arguments)}; +a._spine_skin_get_name=function(){return(a._spine_skin_get_name=a.asm.spine_skin_get_name).apply(null,arguments)};a._spine_skin_add_skin=function(){return(a._spine_skin_add_skin=a.asm.spine_skin_add_skin).apply(null,arguments)};a._spine_skin_copy_skin=function(){return(a._spine_skin_copy_skin=a.asm.spine_skin_copy_skin).apply(null,arguments)};a._spine_skin_get_entries=function(){return(a._spine_skin_get_entries=a.asm.spine_skin_get_entries).apply(null,arguments)}; +a._spine_skin_entries_get_num_entries=function(){return(a._spine_skin_entries_get_num_entries=a.asm.spine_skin_entries_get_num_entries).apply(null,arguments)};a._spine_skin_entries_get_entry=function(){return(a._spine_skin_entries_get_entry=a.asm.spine_skin_entries_get_entry).apply(null,arguments)};a._spine_skin_entries_dispose=function(){return(a._spine_skin_entries_dispose=a.asm.spine_skin_entries_dispose).apply(null,arguments)}; +a._spine_skin_entry_get_slot_index=function(){return(a._spine_skin_entry_get_slot_index=a.asm.spine_skin_entry_get_slot_index).apply(null,arguments)};a._spine_skin_entry_get_name=function(){return(a._spine_skin_entry_get_name=a.asm.spine_skin_entry_get_name).apply(null,arguments)};a._spine_skin_entry_get_attachment=function(){return(a._spine_skin_entry_get_attachment=a.asm.spine_skin_entry_get_attachment).apply(null,arguments)}; +a._spine_skin_get_num_bones=function(){return(a._spine_skin_get_num_bones=a.asm.spine_skin_get_num_bones).apply(null,arguments)};a._spine_skin_get_bones=function(){return(a._spine_skin_get_bones=a.asm.spine_skin_get_bones).apply(null,arguments)};a._spine_skin_get_num_constraints=function(){return(a._spine_skin_get_num_constraints=a.asm.spine_skin_get_num_constraints).apply(null,arguments)}; +a._spine_skin_get_constraints=function(){return(a._spine_skin_get_constraints=a.asm.spine_skin_get_constraints).apply(null,arguments)};a._spine_skin_create=function(){return(a._spine_skin_create=a.asm.spine_skin_create).apply(null,arguments)};a._spine_skin_dispose=function(){return(a._spine_skin_dispose=a.asm.spine_skin_dispose).apply(null,arguments)};a._spine_constraint_data_get_type=function(){return(a._spine_constraint_data_get_type=a.asm.spine_constraint_data_get_type).apply(null,arguments)}; +a._spine_constraint_data_get_name=function(){return(a._spine_constraint_data_get_name=a.asm.spine_constraint_data_get_name).apply(null,arguments)};a._spine_constraint_data_get_order=function(){return(a._spine_constraint_data_get_order=a.asm.spine_constraint_data_get_order).apply(null,arguments)};a._spine_constraint_data_set_order=function(){return(a._spine_constraint_data_set_order=a.asm.spine_constraint_data_set_order).apply(null,arguments)}; +a._spine_constraint_data_get_is_skin_required=function(){return(a._spine_constraint_data_get_is_skin_required=a.asm.spine_constraint_data_get_is_skin_required).apply(null,arguments)};a._spine_constraint_data_set_is_skin_required=function(){return(a._spine_constraint_data_set_is_skin_required=a.asm.spine_constraint_data_set_is_skin_required).apply(null,arguments)}; +a._spine_ik_constraint_data_get_num_bones=function(){return(a._spine_ik_constraint_data_get_num_bones=a.asm.spine_ik_constraint_data_get_num_bones).apply(null,arguments)};a._spine_ik_constraint_data_get_bones=function(){return(a._spine_ik_constraint_data_get_bones=a.asm.spine_ik_constraint_data_get_bones).apply(null,arguments)};a._spine_ik_constraint_data_get_target=function(){return(a._spine_ik_constraint_data_get_target=a.asm.spine_ik_constraint_data_get_target).apply(null,arguments)}; +a._spine_ik_constraint_data_set_target=function(){return(a._spine_ik_constraint_data_set_target=a.asm.spine_ik_constraint_data_set_target).apply(null,arguments)};a._spine_ik_constraint_data_get_bend_direction=function(){return(a._spine_ik_constraint_data_get_bend_direction=a.asm.spine_ik_constraint_data_get_bend_direction).apply(null,arguments)}; +a._spine_ik_constraint_data_set_bend_direction=function(){return(a._spine_ik_constraint_data_set_bend_direction=a.asm.spine_ik_constraint_data_set_bend_direction).apply(null,arguments)};a._spine_ik_constraint_data_get_compress=function(){return(a._spine_ik_constraint_data_get_compress=a.asm.spine_ik_constraint_data_get_compress).apply(null,arguments)}; +a._spine_ik_constraint_data_set_compress=function(){return(a._spine_ik_constraint_data_set_compress=a.asm.spine_ik_constraint_data_set_compress).apply(null,arguments)};a._spine_ik_constraint_data_get_stretch=function(){return(a._spine_ik_constraint_data_get_stretch=a.asm.spine_ik_constraint_data_get_stretch).apply(null,arguments)};a._spine_ik_constraint_data_set_stretch=function(){return(a._spine_ik_constraint_data_set_stretch=a.asm.spine_ik_constraint_data_set_stretch).apply(null,arguments)}; +a._spine_ik_constraint_data_get_uniform=function(){return(a._spine_ik_constraint_data_get_uniform=a.asm.spine_ik_constraint_data_get_uniform).apply(null,arguments)};a._spine_ik_constraint_data_get_mix=function(){return(a._spine_ik_constraint_data_get_mix=a.asm.spine_ik_constraint_data_get_mix).apply(null,arguments)};a._spine_ik_constraint_data_set_mix=function(){return(a._spine_ik_constraint_data_set_mix=a.asm.spine_ik_constraint_data_set_mix).apply(null,arguments)}; +a._spine_ik_constraint_data_get_softness=function(){return(a._spine_ik_constraint_data_get_softness=a.asm.spine_ik_constraint_data_get_softness).apply(null,arguments)};a._spine_ik_constraint_data_set_softness=function(){return(a._spine_ik_constraint_data_set_softness=a.asm.spine_ik_constraint_data_set_softness).apply(null,arguments)};a._spine_ik_constraint_update=function(){return(a._spine_ik_constraint_update=a.asm.spine_ik_constraint_update).apply(null,arguments)}; +a._spine_ik_constraint_get_order=function(){return(a._spine_ik_constraint_get_order=a.asm.spine_ik_constraint_get_order).apply(null,arguments)};a._spine_ik_constraint_get_data=function(){return(a._spine_ik_constraint_get_data=a.asm.spine_ik_constraint_get_data).apply(null,arguments)};a._spine_ik_constraint_get_num_bones=function(){return(a._spine_ik_constraint_get_num_bones=a.asm.spine_ik_constraint_get_num_bones).apply(null,arguments)}; +a._spine_ik_constraint_get_bones=function(){return(a._spine_ik_constraint_get_bones=a.asm.spine_ik_constraint_get_bones).apply(null,arguments)};a._spine_ik_constraint_get_target=function(){return(a._spine_ik_constraint_get_target=a.asm.spine_ik_constraint_get_target).apply(null,arguments)};a._spine_ik_constraint_set_target=function(){return(a._spine_ik_constraint_set_target=a.asm.spine_ik_constraint_set_target).apply(null,arguments)}; +a._spine_ik_constraint_get_bend_direction=function(){return(a._spine_ik_constraint_get_bend_direction=a.asm.spine_ik_constraint_get_bend_direction).apply(null,arguments)};a._spine_ik_constraint_set_bend_direction=function(){return(a._spine_ik_constraint_set_bend_direction=a.asm.spine_ik_constraint_set_bend_direction).apply(null,arguments)};a._spine_ik_constraint_get_compress=function(){return(a._spine_ik_constraint_get_compress=a.asm.spine_ik_constraint_get_compress).apply(null,arguments)}; +a._spine_ik_constraint_set_compress=function(){return(a._spine_ik_constraint_set_compress=a.asm.spine_ik_constraint_set_compress).apply(null,arguments)};a._spine_ik_constraint_get_stretch=function(){return(a._spine_ik_constraint_get_stretch=a.asm.spine_ik_constraint_get_stretch).apply(null,arguments)};a._spine_ik_constraint_set_stretch=function(){return(a._spine_ik_constraint_set_stretch=a.asm.spine_ik_constraint_set_stretch).apply(null,arguments)}; +a._spine_ik_constraint_get_mix=function(){return(a._spine_ik_constraint_get_mix=a.asm.spine_ik_constraint_get_mix).apply(null,arguments)};a._spine_ik_constraint_set_mix=function(){return(a._spine_ik_constraint_set_mix=a.asm.spine_ik_constraint_set_mix).apply(null,arguments)};a._spine_ik_constraint_get_softness=function(){return(a._spine_ik_constraint_get_softness=a.asm.spine_ik_constraint_get_softness).apply(null,arguments)}; +a._spine_ik_constraint_set_softness=function(){return(a._spine_ik_constraint_set_softness=a.asm.spine_ik_constraint_set_softness).apply(null,arguments)};a._spine_ik_constraint_get_is_active=function(){return(a._spine_ik_constraint_get_is_active=a.asm.spine_ik_constraint_get_is_active).apply(null,arguments)};a._spine_ik_constraint_set_is_active=function(){return(a._spine_ik_constraint_set_is_active=a.asm.spine_ik_constraint_set_is_active).apply(null,arguments)}; +a._spine_transform_constraint_data_get_num_bones=function(){return(a._spine_transform_constraint_data_get_num_bones=a.asm.spine_transform_constraint_data_get_num_bones).apply(null,arguments)};a._spine_transform_constraint_data_get_bones=function(){return(a._spine_transform_constraint_data_get_bones=a.asm.spine_transform_constraint_data_get_bones).apply(null,arguments)}; +a._spine_transform_constraint_data_get_target=function(){return(a._spine_transform_constraint_data_get_target=a.asm.spine_transform_constraint_data_get_target).apply(null,arguments)};a._spine_transform_constraint_data_set_target=function(){return(a._spine_transform_constraint_data_set_target=a.asm.spine_transform_constraint_data_set_target).apply(null,arguments)}; +a._spine_transform_constraint_data_get_mix_rotate=function(){return(a._spine_transform_constraint_data_get_mix_rotate=a.asm.spine_transform_constraint_data_get_mix_rotate).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_rotate=function(){return(a._spine_transform_constraint_data_set_mix_rotate=a.asm.spine_transform_constraint_data_set_mix_rotate).apply(null,arguments)}; +a._spine_transform_constraint_data_get_mix_x=function(){return(a._spine_transform_constraint_data_get_mix_x=a.asm.spine_transform_constraint_data_get_mix_x).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_x=function(){return(a._spine_transform_constraint_data_set_mix_x=a.asm.spine_transform_constraint_data_set_mix_x).apply(null,arguments)}; +a._spine_transform_constraint_data_get_mix_y=function(){return(a._spine_transform_constraint_data_get_mix_y=a.asm.spine_transform_constraint_data_get_mix_y).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_y=function(){return(a._spine_transform_constraint_data_set_mix_y=a.asm.spine_transform_constraint_data_set_mix_y).apply(null,arguments)}; +a._spine_transform_constraint_data_get_mix_scale_x=function(){return(a._spine_transform_constraint_data_get_mix_scale_x=a.asm.spine_transform_constraint_data_get_mix_scale_x).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_scale_x=function(){return(a._spine_transform_constraint_data_set_mix_scale_x=a.asm.spine_transform_constraint_data_set_mix_scale_x).apply(null,arguments)}; +a._spine_transform_constraint_data_get_mix_scale_y=function(){return(a._spine_transform_constraint_data_get_mix_scale_y=a.asm.spine_transform_constraint_data_get_mix_scale_y).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_scale_y=function(){return(a._spine_transform_constraint_data_set_mix_scale_y=a.asm.spine_transform_constraint_data_set_mix_scale_y).apply(null,arguments)}; +a._spine_transform_constraint_data_get_mix_shear_y=function(){return(a._spine_transform_constraint_data_get_mix_shear_y=a.asm.spine_transform_constraint_data_get_mix_shear_y).apply(null,arguments)};a._spine_transform_constraint_data_set_mix_shear_y=function(){return(a._spine_transform_constraint_data_set_mix_shear_y=a.asm.spine_transform_constraint_data_set_mix_shear_y).apply(null,arguments)}; +a._spine_transform_constraint_data_get_offset_rotation=function(){return(a._spine_transform_constraint_data_get_offset_rotation=a.asm.spine_transform_constraint_data_get_offset_rotation).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_rotation=function(){return(a._spine_transform_constraint_data_set_offset_rotation=a.asm.spine_transform_constraint_data_set_offset_rotation).apply(null,arguments)}; +a._spine_transform_constraint_data_get_offset_x=function(){return(a._spine_transform_constraint_data_get_offset_x=a.asm.spine_transform_constraint_data_get_offset_x).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_x=function(){return(a._spine_transform_constraint_data_set_offset_x=a.asm.spine_transform_constraint_data_set_offset_x).apply(null,arguments)}; +a._spine_transform_constraint_data_get_offset_y=function(){return(a._spine_transform_constraint_data_get_offset_y=a.asm.spine_transform_constraint_data_get_offset_y).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_y=function(){return(a._spine_transform_constraint_data_set_offset_y=a.asm.spine_transform_constraint_data_set_offset_y).apply(null,arguments)}; +a._spine_transform_constraint_data_get_offset_scale_x=function(){return(a._spine_transform_constraint_data_get_offset_scale_x=a.asm.spine_transform_constraint_data_get_offset_scale_x).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_scale_x=function(){return(a._spine_transform_constraint_data_set_offset_scale_x=a.asm.spine_transform_constraint_data_set_offset_scale_x).apply(null,arguments)}; +a._spine_transform_constraint_data_get_offset_scale_y=function(){return(a._spine_transform_constraint_data_get_offset_scale_y=a.asm.spine_transform_constraint_data_get_offset_scale_y).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_scale_y=function(){return(a._spine_transform_constraint_data_set_offset_scale_y=a.asm.spine_transform_constraint_data_set_offset_scale_y).apply(null,arguments)}; +a._spine_transform_constraint_data_get_offset_shear_y=function(){return(a._spine_transform_constraint_data_get_offset_shear_y=a.asm.spine_transform_constraint_data_get_offset_shear_y).apply(null,arguments)};a._spine_transform_constraint_data_set_offset_shear_y=function(){return(a._spine_transform_constraint_data_set_offset_shear_y=a.asm.spine_transform_constraint_data_set_offset_shear_y).apply(null,arguments)}; +a._spine_transform_constraint_data_get_is_relative=function(){return(a._spine_transform_constraint_data_get_is_relative=a.asm.spine_transform_constraint_data_get_is_relative).apply(null,arguments)};a._spine_transform_constraint_data_set_is_relative=function(){return(a._spine_transform_constraint_data_set_is_relative=a.asm.spine_transform_constraint_data_set_is_relative).apply(null,arguments)}; +a._spine_transform_constraint_data_get_is_local=function(){return(a._spine_transform_constraint_data_get_is_local=a.asm.spine_transform_constraint_data_get_is_local).apply(null,arguments)};a._spine_transform_constraint_data_set_is_local=function(){return(a._spine_transform_constraint_data_set_is_local=a.asm.spine_transform_constraint_data_set_is_local).apply(null,arguments)}; +a._spine_transform_constraint_update=function(){return(a._spine_transform_constraint_update=a.asm.spine_transform_constraint_update).apply(null,arguments)};a._spine_transform_constraint_get_order=function(){return(a._spine_transform_constraint_get_order=a.asm.spine_transform_constraint_get_order).apply(null,arguments)};a._spine_transform_constraint_get_data=function(){return(a._spine_transform_constraint_get_data=a.asm.spine_transform_constraint_get_data).apply(null,arguments)}; +a._spine_transform_constraint_get_num_bones=function(){return(a._spine_transform_constraint_get_num_bones=a.asm.spine_transform_constraint_get_num_bones).apply(null,arguments)};a._spine_transform_constraint_get_bones=function(){return(a._spine_transform_constraint_get_bones=a.asm.spine_transform_constraint_get_bones).apply(null,arguments)};a._spine_transform_constraint_get_target=function(){return(a._spine_transform_constraint_get_target=a.asm.spine_transform_constraint_get_target).apply(null,arguments)}; +a._spine_transform_constraint_set_target=function(){return(a._spine_transform_constraint_set_target=a.asm.spine_transform_constraint_set_target).apply(null,arguments)};a._spine_transform_constraint_get_mix_rotate=function(){return(a._spine_transform_constraint_get_mix_rotate=a.asm.spine_transform_constraint_get_mix_rotate).apply(null,arguments)}; +a._spine_transform_constraint_set_mix_rotate=function(){return(a._spine_transform_constraint_set_mix_rotate=a.asm.spine_transform_constraint_set_mix_rotate).apply(null,arguments)};a._spine_transform_constraint_get_mix_x=function(){return(a._spine_transform_constraint_get_mix_x=a.asm.spine_transform_constraint_get_mix_x).apply(null,arguments)};a._spine_transform_constraint_set_mix_x=function(){return(a._spine_transform_constraint_set_mix_x=a.asm.spine_transform_constraint_set_mix_x).apply(null,arguments)}; +a._spine_transform_constraint_get_mix_y=function(){return(a._spine_transform_constraint_get_mix_y=a.asm.spine_transform_constraint_get_mix_y).apply(null,arguments)};a._spine_transform_constraint_set_mix_y=function(){return(a._spine_transform_constraint_set_mix_y=a.asm.spine_transform_constraint_set_mix_y).apply(null,arguments)}; +a._spine_transform_constraint_get_mix_scale_x=function(){return(a._spine_transform_constraint_get_mix_scale_x=a.asm.spine_transform_constraint_get_mix_scale_x).apply(null,arguments)};a._spine_transform_constraint_set_mix_scale_x=function(){return(a._spine_transform_constraint_set_mix_scale_x=a.asm.spine_transform_constraint_set_mix_scale_x).apply(null,arguments)}; +a._spine_transform_constraint_get_mix_scale_y=function(){return(a._spine_transform_constraint_get_mix_scale_y=a.asm.spine_transform_constraint_get_mix_scale_y).apply(null,arguments)};a._spine_transform_constraint_set_mix_scale_y=function(){return(a._spine_transform_constraint_set_mix_scale_y=a.asm.spine_transform_constraint_set_mix_scale_y).apply(null,arguments)}; +a._spine_transform_constraint_get_mix_shear_y=function(){return(a._spine_transform_constraint_get_mix_shear_y=a.asm.spine_transform_constraint_get_mix_shear_y).apply(null,arguments)};a._spine_transform_constraint_set_mix_shear_y=function(){return(a._spine_transform_constraint_set_mix_shear_y=a.asm.spine_transform_constraint_set_mix_shear_y).apply(null,arguments)}; +a._spine_transform_constraint_get_is_active=function(){return(a._spine_transform_constraint_get_is_active=a.asm.spine_transform_constraint_get_is_active).apply(null,arguments)};a._spine_transform_constraint_set_is_active=function(){return(a._spine_transform_constraint_set_is_active=a.asm.spine_transform_constraint_set_is_active).apply(null,arguments)}; +a._spine_path_constraint_data_get_num_bones=function(){return(a._spine_path_constraint_data_get_num_bones=a.asm.spine_path_constraint_data_get_num_bones).apply(null,arguments)};a._spine_path_constraint_data_get_bones=function(){return(a._spine_path_constraint_data_get_bones=a.asm.spine_path_constraint_data_get_bones).apply(null,arguments)};a._spine_path_constraint_data_get_target=function(){return(a._spine_path_constraint_data_get_target=a.asm.spine_path_constraint_data_get_target).apply(null,arguments)}; +a._spine_path_constraint_data_set_target=function(){return(a._spine_path_constraint_data_set_target=a.asm.spine_path_constraint_data_set_target).apply(null,arguments)};a._spine_path_constraint_data_get_position_mode=function(){return(a._spine_path_constraint_data_get_position_mode=a.asm.spine_path_constraint_data_get_position_mode).apply(null,arguments)}; +a._spine_path_constraint_data_set_position_mode=function(){return(a._spine_path_constraint_data_set_position_mode=a.asm.spine_path_constraint_data_set_position_mode).apply(null,arguments)};a._spine_path_constraint_data_get_spacing_mode=function(){return(a._spine_path_constraint_data_get_spacing_mode=a.asm.spine_path_constraint_data_get_spacing_mode).apply(null,arguments)}; +a._spine_path_constraint_data_set_spacing_mode=function(){return(a._spine_path_constraint_data_set_spacing_mode=a.asm.spine_path_constraint_data_set_spacing_mode).apply(null,arguments)};a._spine_path_constraint_data_get_rotate_mode=function(){return(a._spine_path_constraint_data_get_rotate_mode=a.asm.spine_path_constraint_data_get_rotate_mode).apply(null,arguments)}; +a._spine_path_constraint_data_set_rotate_mode=function(){return(a._spine_path_constraint_data_set_rotate_mode=a.asm.spine_path_constraint_data_set_rotate_mode).apply(null,arguments)};a._spine_path_constraint_data_get_offset_rotation=function(){return(a._spine_path_constraint_data_get_offset_rotation=a.asm.spine_path_constraint_data_get_offset_rotation).apply(null,arguments)}; +a._spine_path_constraint_data_set_offset_rotation=function(){return(a._spine_path_constraint_data_set_offset_rotation=a.asm.spine_path_constraint_data_set_offset_rotation).apply(null,arguments)};a._spine_path_constraint_data_get_position=function(){return(a._spine_path_constraint_data_get_position=a.asm.spine_path_constraint_data_get_position).apply(null,arguments)}; +a._spine_path_constraint_data_set_position=function(){return(a._spine_path_constraint_data_set_position=a.asm.spine_path_constraint_data_set_position).apply(null,arguments)};a._spine_path_constraint_data_get_spacing=function(){return(a._spine_path_constraint_data_get_spacing=a.asm.spine_path_constraint_data_get_spacing).apply(null,arguments)}; +a._spine_path_constraint_data_set_spacing=function(){return(a._spine_path_constraint_data_set_spacing=a.asm.spine_path_constraint_data_set_spacing).apply(null,arguments)};a._spine_path_constraint_data_get_mix_rotate=function(){return(a._spine_path_constraint_data_get_mix_rotate=a.asm.spine_path_constraint_data_get_mix_rotate).apply(null,arguments)}; +a._spine_path_constraint_data_set_mix_rotate=function(){return(a._spine_path_constraint_data_set_mix_rotate=a.asm.spine_path_constraint_data_set_mix_rotate).apply(null,arguments)};a._spine_path_constraint_data_get_mix_x=function(){return(a._spine_path_constraint_data_get_mix_x=a.asm.spine_path_constraint_data_get_mix_x).apply(null,arguments)};a._spine_path_constraint_data_set_mix_x=function(){return(a._spine_path_constraint_data_set_mix_x=a.asm.spine_path_constraint_data_set_mix_x).apply(null,arguments)}; +a._spine_path_constraint_data_get_mix_y=function(){return(a._spine_path_constraint_data_get_mix_y=a.asm.spine_path_constraint_data_get_mix_y).apply(null,arguments)};a._spine_path_constraint_data_set_mix_y=function(){return(a._spine_path_constraint_data_set_mix_y=a.asm.spine_path_constraint_data_set_mix_y).apply(null,arguments)};a._spine_path_constraint_update=function(){return(a._spine_path_constraint_update=a.asm.spine_path_constraint_update).apply(null,arguments)}; +a._spine_path_constraint_get_order=function(){return(a._spine_path_constraint_get_order=a.asm.spine_path_constraint_get_order).apply(null,arguments)};a._spine_path_constraint_get_data=function(){return(a._spine_path_constraint_get_data=a.asm.spine_path_constraint_get_data).apply(null,arguments)};a._spine_path_constraint_get_num_bones=function(){return(a._spine_path_constraint_get_num_bones=a.asm.spine_path_constraint_get_num_bones).apply(null,arguments)}; +a._spine_path_constraint_get_bones=function(){return(a._spine_path_constraint_get_bones=a.asm.spine_path_constraint_get_bones).apply(null,arguments)};a._spine_path_constraint_get_target=function(){return(a._spine_path_constraint_get_target=a.asm.spine_path_constraint_get_target).apply(null,arguments)};a._spine_path_constraint_set_target=function(){return(a._spine_path_constraint_set_target=a.asm.spine_path_constraint_set_target).apply(null,arguments)}; +a._spine_path_constraint_get_position=function(){return(a._spine_path_constraint_get_position=a.asm.spine_path_constraint_get_position).apply(null,arguments)};a._spine_path_constraint_set_position=function(){return(a._spine_path_constraint_set_position=a.asm.spine_path_constraint_set_position).apply(null,arguments)};a._spine_path_constraint_get_spacing=function(){return(a._spine_path_constraint_get_spacing=a.asm.spine_path_constraint_get_spacing).apply(null,arguments)}; +a._spine_path_constraint_set_spacing=function(){return(a._spine_path_constraint_set_spacing=a.asm.spine_path_constraint_set_spacing).apply(null,arguments)};a._spine_path_constraint_get_mix_rotate=function(){return(a._spine_path_constraint_get_mix_rotate=a.asm.spine_path_constraint_get_mix_rotate).apply(null,arguments)};a._spine_path_constraint_set_mix_rotate=function(){return(a._spine_path_constraint_set_mix_rotate=a.asm.spine_path_constraint_set_mix_rotate).apply(null,arguments)}; +a._spine_path_constraint_get_mix_x=function(){return(a._spine_path_constraint_get_mix_x=a.asm.spine_path_constraint_get_mix_x).apply(null,arguments)};a._spine_path_constraint_set_mix_x=function(){return(a._spine_path_constraint_set_mix_x=a.asm.spine_path_constraint_set_mix_x).apply(null,arguments)};a._spine_path_constraint_get_mix_y=function(){return(a._spine_path_constraint_get_mix_y=a.asm.spine_path_constraint_get_mix_y).apply(null,arguments)}; +a._spine_path_constraint_set_mix_y=function(){return(a._spine_path_constraint_set_mix_y=a.asm.spine_path_constraint_set_mix_y).apply(null,arguments)};a._spine_path_constraint_get_is_active=function(){return(a._spine_path_constraint_get_is_active=a.asm.spine_path_constraint_get_is_active).apply(null,arguments)};a._spine_path_constraint_set_is_active=function(){return(a._spine_path_constraint_set_is_active=a.asm.spine_path_constraint_set_is_active).apply(null,arguments)}; +a._spine_sequence_apply=function(){return(a._spine_sequence_apply=a.asm.spine_sequence_apply).apply(null,arguments)};a._spine_sequence_get_path=function(){return(a._spine_sequence_get_path=a.asm.spine_sequence_get_path).apply(null,arguments)};a._spine_sequence_get_id=function(){return(a._spine_sequence_get_id=a.asm.spine_sequence_get_id).apply(null,arguments)};a._spine_sequence_set_id=function(){return(a._spine_sequence_set_id=a.asm.spine_sequence_set_id).apply(null,arguments)}; +a._spine_sequence_get_start=function(){return(a._spine_sequence_get_start=a.asm.spine_sequence_get_start).apply(null,arguments)};a._spine_sequence_set_start=function(){return(a._spine_sequence_set_start=a.asm.spine_sequence_set_start).apply(null,arguments)};a._spine_sequence_get_digits=function(){return(a._spine_sequence_get_digits=a.asm.spine_sequence_get_digits).apply(null,arguments)}; +a._spine_sequence_set_digits=function(){return(a._spine_sequence_set_digits=a.asm.spine_sequence_set_digits).apply(null,arguments)};a._spine_sequence_get_setup_index=function(){return(a._spine_sequence_get_setup_index=a.asm.spine_sequence_get_setup_index).apply(null,arguments)};a._spine_sequence_set_setup_index=function(){return(a._spine_sequence_set_setup_index=a.asm.spine_sequence_set_setup_index).apply(null,arguments)}; +a._spine_sequence_get_num_regions=function(){return(a._spine_sequence_get_num_regions=a.asm.spine_sequence_get_num_regions).apply(null,arguments)};a._spine_sequence_get_regions=function(){return(a._spine_sequence_get_regions=a.asm.spine_sequence_get_regions).apply(null,arguments)};a._spine_texture_region_get_texture=function(){return(a._spine_texture_region_get_texture=a.asm.spine_texture_region_get_texture).apply(null,arguments)}; +a._spine_texture_region_set_texture=function(){return(a._spine_texture_region_set_texture=a.asm.spine_texture_region_set_texture).apply(null,arguments)};a._spine_texture_region_get_u=function(){return(a._spine_texture_region_get_u=a.asm.spine_texture_region_get_u).apply(null,arguments)};a._spine_texture_region_set_u=function(){return(a._spine_texture_region_set_u=a.asm.spine_texture_region_set_u).apply(null,arguments)}; +a._spine_texture_region_get_v=function(){return(a._spine_texture_region_get_v=a.asm.spine_texture_region_get_v).apply(null,arguments)};a._spine_texture_region_set_v=function(){return(a._spine_texture_region_set_v=a.asm.spine_texture_region_set_v).apply(null,arguments)};a._spine_texture_region_get_u2=function(){return(a._spine_texture_region_get_u2=a.asm.spine_texture_region_get_u2).apply(null,arguments)}; +a._spine_texture_region_set_u2=function(){return(a._spine_texture_region_set_u2=a.asm.spine_texture_region_set_u2).apply(null,arguments)};a._spine_texture_region_get_v2=function(){return(a._spine_texture_region_get_v2=a.asm.spine_texture_region_get_v2).apply(null,arguments)};a._spine_texture_region_set_v2=function(){return(a._spine_texture_region_set_v2=a.asm.spine_texture_region_set_v2).apply(null,arguments)}; +a._spine_texture_region_get_degrees=function(){return(a._spine_texture_region_get_degrees=a.asm.spine_texture_region_get_degrees).apply(null,arguments)};a._spine_texture_region_set_degrees=function(){return(a._spine_texture_region_set_degrees=a.asm.spine_texture_region_set_degrees).apply(null,arguments)};a._spine_texture_region_get_offset_x=function(){return(a._spine_texture_region_get_offset_x=a.asm.spine_texture_region_get_offset_x).apply(null,arguments)}; +a._spine_texture_region_set_offset_x=function(){return(a._spine_texture_region_set_offset_x=a.asm.spine_texture_region_set_offset_x).apply(null,arguments)};a._spine_texture_region_get_offset_y=function(){return(a._spine_texture_region_get_offset_y=a.asm.spine_texture_region_get_offset_y).apply(null,arguments)};a._spine_texture_region_set_offset_y=function(){return(a._spine_texture_region_set_offset_y=a.asm.spine_texture_region_set_offset_y).apply(null,arguments)}; +a._spine_texture_region_get_width=function(){return(a._spine_texture_region_get_width=a.asm.spine_texture_region_get_width).apply(null,arguments)};a._spine_texture_region_set_width=function(){return(a._spine_texture_region_set_width=a.asm.spine_texture_region_set_width).apply(null,arguments)};a._spine_texture_region_get_height=function(){return(a._spine_texture_region_get_height=a.asm.spine_texture_region_get_height).apply(null,arguments)}; +a._spine_texture_region_set_height=function(){return(a._spine_texture_region_set_height=a.asm.spine_texture_region_set_height).apply(null,arguments)};a._spine_texture_region_get_original_width=function(){return(a._spine_texture_region_get_original_width=a.asm.spine_texture_region_get_original_width).apply(null,arguments)};a._spine_texture_region_set_original_width=function(){return(a._spine_texture_region_set_original_width=a.asm.spine_texture_region_set_original_width).apply(null,arguments)}; +a._spine_texture_region_get_original_height=function(){return(a._spine_texture_region_get_original_height=a.asm.spine_texture_region_get_original_height).apply(null,arguments)};a._spine_texture_region_set_original_height=function(){return(a._spine_texture_region_set_original_height=a.asm.spine_texture_region_set_original_height).apply(null,arguments)};a.___errno_location=function(){return(a.___errno_location=a.asm.__errno_location).apply(null,arguments)}; +a.stackSave=function(){return(a.stackSave=a.asm.stackSave).apply(null,arguments)};a.stackRestore=function(){return(a.stackRestore=a.asm.stackRestore).apply(null,arguments)};a.stackAlloc=function(){return(a.stackAlloc=a.asm.stackAlloc).apply(null,arguments)};a.dynCall_jiji=function(){return(a.dynCall_jiji=a.asm.dynCall_jiji).apply(null,arguments)};var Z;R=function sa(){Z||ta();Z||(R=sa)}; +function ta(){function b(){if(!Z&&(Z=!0,a.calledRun=!0,!B)){V(ca);h(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;){var c=a.postRun.shift();da.unshift(c)}V(da)}}if(!(0` representing the entire array. This pointer is +/// the equivalent of a char pointer (`const char*`) in C code. +class Utf8 extends Opaque {} + +/// Extension method for converting a`Pointer` to a [String]. +extension Utf8Pointer on Pointer { + /// The number of UTF-8 code units in this zero-terminated UTF-8 string. + /// + /// The UTF-8 code units of the strings are the non-zero code units up to the + /// first zero code unit. + int get length { + _ensureNotNullptr('length'); + final codeUnits = cast(); + return _length(codeUnits); + } + + /// Converts this UTF-8 encoded string to a Dart string. + /// + /// Decodes the UTF-8 code units of this zero-terminated byte array as + /// Unicode code points and creates a Dart string containing those code + /// points. + /// + /// If [length] is provided, zero-termination is ignored and the result can + /// contain NUL characters. + /// + /// If [length] is not provided, the returned string is the string up til + /// but not including the first NUL character. + String toDartString({int? length}) { + _ensureNotNullptr('toDartString'); + final codeUnits = cast(); + if (length != null) { + RangeError.checkNotNegative(length, 'length'); + } else { + length = _length(codeUnits); + } + return utf8.decode(codeUnits.asTypedList(length)); + } + + static int _length(Pointer codeUnits) { + var length = 0; + while (codeUnits[length] != 0) { + length++; + } + return length; + } + + void _ensureNotNullptr(String operation) { + if (this == nullptr) { + throw UnsupportedError("Operation '$operation' not allowed on a 'nullptr'."); + } + } +} + +/// Extension method for converting a [String] to a `Pointer`. +extension StringUtf8Pointer on String { + /// Creates a zero-terminated [Utf8] code-unit array from this String. + /// + /// If this [String] contains NUL characters, converting it back to a string + /// using [Utf8Pointer.toDartString] will truncate the result if a length is + /// not passed. + /// + /// Unpaired surrogate code points in this [String] will be encoded as + /// replacement characters (U+FFFD, encoded as the bytes 0xEF 0xBF 0xBD) in + /// the UTF-8 encoded result. See [Utf8Encoder] for details on encoding. + /// + /// Returns an [allocator]-allocated pointer to the result. + Pointer toNativeUtf8(Allocator allocator) { + final units = utf8.encode(this); + final Pointer result = allocator(units.length + 1); + final Uint8List nativeString = result.asTypedList(units.length + 1); + nativeString.setAll(0, units); + nativeString[units.length] = 0; + return result.cast(); + } +} diff --git a/spine-flutter/lib/init.dart b/spine-flutter/lib/init.dart new file mode 100644 index 000000000..7655d5e44 --- /dev/null +++ b/spine-flutter/lib/init.dart @@ -0,0 +1,58 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated September 24, 2021. Replaces all prior versions. + * + * Copyright (c) 2013-2021, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +import 'dart:ffi'; +import 'dart:io'; + +import 'package:ffi/ffi.dart'; + +const String _libName = 'spine_flutter'; +final DynamicLibrary _dylib = () { + if (Platform.isMacOS || Platform.isIOS) { + return DynamicLibrary.open('$_libName.framework/$_libName'); + } + if (Platform.isAndroid || Platform.isLinux) { + return DynamicLibrary.open('lib$_libName.so'); + } + if (Platform.isWindows) { + return DynamicLibrary.open('$_libName.dll'); + } + throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); +}(); + +class SpineFlutterFFI { + DynamicLibrary dylib; + Allocator allocator; + + SpineFlutterFFI(this.dylib, this.allocator); +} + +Future initSpineFlutterFFI() async { + return SpineFlutterFFI(_dylib, malloc); +} diff --git a/spine-flutter/lib/init_web.dart b/spine-flutter/lib/init_web.dart new file mode 100644 index 000000000..34fc91d50 --- /dev/null +++ b/spine-flutter/lib/init_web.dart @@ -0,0 +1,105 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated September 24, 2021. Replaces all prior versions. + * + * Copyright (c) 2013-2021, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +// ignore_for_file: type_argument_not_matching_bounds +import 'package:flutter/services.dart'; +import 'package:inject_js/inject_js.dart' as js; +import 'package:web_ffi_fork/web_ffi.dart'; +import 'package:web_ffi_fork/web_ffi_modules.dart'; + +import 'spine_flutter_bindings_generated.dart'; + +Module? _module; + +class SpineFlutterFFI { + final DynamicLibrary dylib; + final Allocator allocator; + + SpineFlutterFFI(this.dylib, this.allocator); +} + +Future initSpineFlutterFFI() async { + if (_module == null) { + Memory.init(); + + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + registerOpaqueType(); + + await js.importLibrary('assets/packages/spine_flutter/lib/assets/libspine_flutter.js'); + Uint8List wasmBinaries = + (await rootBundle.load('packages/spine_flutter/lib/assets/libspine_flutter.wasm')).buffer.asUint8List(); + _module = await EmscriptenModule.compile(wasmBinaries, 'libspine_flutter'); + } + Module? m = _module; + if (m != null) { + final dylib = DynamicLibrary.fromModule(m); + return SpineFlutterFFI(dylib, dylib.boundMemory); + } else { + throw Exception("Couldn't load libspine-flutter.js/.wasm"); + } +} diff --git a/spine-flutter/lib/spine_flutter.dart b/spine-flutter/lib/spine_flutter.dart new file mode 100644 index 000000000..6a053a31a --- /dev/null +++ b/spine-flutter/lib/spine_flutter.dart @@ -0,0 +1,4088 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated September 24, 2021. Replaces all prior versions. + * + * Copyright (c) 2013-2021, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +import 'dart:convert' as convert; +import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/material.dart' as material; +import 'package:flutter/rendering.dart' as rendering; +import 'package:flutter/services.dart'; +import 'package:http/http.dart' as http; +import 'package:path/path.dart' as path; +import 'package:raw_image_provider/raw_image_provider.dart'; + +import 'ffi_proxy.dart'; +import 'init.dart' if (dart.library.html) 'init_web.dart'; +import 'spine_flutter_bindings_generated.dart'; + +export 'spine_widget.dart'; + +late SpineFlutterBindings _bindings; +late Allocator _allocator; + +Future initSpineFlutter({bool enableMemoryDebugging = false}) async { + final ffi = await initSpineFlutterFFI(); + _bindings = SpineFlutterBindings(ffi.dylib); + _allocator = ffi.allocator; + if (enableMemoryDebugging) _bindings.spine_enable_debug_extension(-1); + return; +} + +int majorVersion() => _bindings.spine_major_version(); + +int minorVersion() => _bindings.spine_minor_version(); + +void reportLeaks() => _bindings.spine_report_leaks(); + +/// A color made of red, green, blue, and alpha components, +/// ranging from 0-1. +class Color { + double r; + double g; + double b; + double a; + + Color(this.r, this.g, this.b, this.a); +} + +/// Bounds denoted by the top left corner coordinates [x] and [y] +/// and the [width] and [height]. +class Bounds { + double x; + double y; + double width; + double height; + + Bounds(this.x, this.y, this.width, this.height); +} + +/// A two-dimensional vector with [x] and [y] components. +class Vec2 { + double x; + double y; + + Vec2(this.x, this.y); +} + +/// Atlas data loaded from a `.atlas` file and its corresponding `.png` files. For each atlas image, +/// a corresponding [Image] and [Paint] is constructed, which are used when rendering a skeleton +/// that uses this atlas. +/// +/// Use the static methods [fromAsset], [fromFile], and [fromHttp] to load an atlas. Call [dispose] +/// when the atlas is no longer in use to release its resources. +class Atlas { + final spine_atlas _atlas; + final List atlasPages; + final List atlasPagePaints; + bool _disposed; + + Atlas._(this._atlas, this.atlasPages, this.atlasPagePaints) : _disposed = false; + + static Future _load(String atlasFileName, Future Function(String name) loadFile) async { + final atlasBytes = await loadFile(atlasFileName); + final atlasData = convert.utf8.decode(atlasBytes); + final atlasDataNative = atlasData.toNativeUtf8(allocator: _allocator); + final atlas = _bindings.spine_atlas_load(atlasDataNative.cast()); + _allocator.free(atlasDataNative); + if (_bindings.spine_atlas_get_error(atlas).address != nullptr.address) { + final Pointer error = _bindings.spine_atlas_get_error(atlas).cast(); + final message = error.toDartString(); + _bindings.spine_atlas_dispose(atlas); + throw Exception("Couldn't load atlas: $message"); + } + + final atlasDir = path.dirname(atlasFileName); + List atlasPages = []; + List atlasPagePaints = []; + final numImagePaths = _bindings.spine_atlas_get_num_image_paths(atlas); + for (int i = 0; i < numImagePaths; i++) { + final Pointer atlasPageFile = _bindings.spine_atlas_get_image_path(atlas, i).cast(); + final imagePath = path.join(atlasDir, atlasPageFile.toDartString()); + var imageData = await loadFile(imagePath); + final Codec codec = await instantiateImageCodec(imageData); + final FrameInfo frameInfo = await codec.getNextFrame(); + final Image image = frameInfo.image; + atlasPages.add(image); + atlasPagePaints.add(Paint() + ..shader = ImageShader(image, TileMode.clamp, TileMode.clamp, Matrix4.identity().storage, filterQuality: FilterQuality.high) + ..isAntiAlias = true); + } + + return Atlas._(atlas, atlasPages, atlasPagePaints); + } + + /// Loads an [Atlas] from the file [atlasFileName] in the root bundle or the optionally provided [bundle]. + /// + /// Throws an [Exception] in case the atlas could not be loaded. + static Future fromAsset(String atlasFileName, {AssetBundle? bundle}) async { + bundle ??= rootBundle; + return _load(atlasFileName, (file) async => (await bundle!.load(file)).buffer.asUint8List()); + } + + /// Loads an [Atlas] from the file [atlasFileName]. + /// + /// Throws an [Exception] in case the atlas could not be loaded. + static Future fromFile(String atlasFileName) async { + return _load(atlasFileName, (file) => File(file).readAsBytes()); + } + + /// Loads an [Atlas] from the URL [atlasURL]. + /// + /// Throws an [Exception] in case the atlas could not be loaded. + static Future fromHttp(String atlasURL) async { + return _load(atlasURL, (file) async { + return (await http.get(Uri.parse(file))).bodyBytes; + }); + } + + /// Disposes the (native) resources of this atlas. The atlas can no longer be + /// used after calling this function. Only the first call to this method will + /// have an effect. Subsequent calls are ignored. + void dispose() { + if (_disposed) return; + _disposed = true; + _bindings.spine_atlas_dispose(_atlas); + for (final image in atlasPages) { + image.dispose(); + } + } +} + +/// Skeleton data loaded from a skeleton `.json` or `.skel` file. Contains bones, slots, constraints, +/// skins, animations, and so on making up a skeleton. Also contains meta data such as the skeletons +/// setup pose bounding box, the Spine editor version it was exported from, and so on. +/// +/// Skeleton data is stateless. Stateful [Skeleton] instances can be constructed from a [SkeletonData] instance. +/// A single [SkeletonData] instance can be shared by multiple [Skeleton] instances. +/// +/// Use the static methods [fromJson], [fromBinary], [fromAsset], [fromFile], and [fromURL] to load +/// skeleton data. Call [dispose] when the skeleton data is no longer in use to free its resources. +/// +/// See [Data objects](http://esotericsoftware.com/spine-runtime-architecture#Data-objects) in the Spine +/// Runtimes Guide. +class SkeletonData { + final spine_skeleton_data _data; + bool _disposed; + + SkeletonData._(this._data) : _disposed = false; + + /// Loads a [SkeletonData] from the [json] string, using the provided [atlas] to resolve attachment + /// images. + /// + /// Throws an [Exception] in case the atlas could not be loaded. + static SkeletonData fromJson(Atlas atlas, String json) { + final jsonNative = json.toNativeUtf8(allocator: _allocator); + final result = _bindings.spine_skeleton_data_load_json(atlas._atlas, jsonNative.cast()); + _allocator.free(jsonNative); + if (_bindings.spine_skeleton_data_result_get_error(result).address != nullptr.address) { + final Pointer error = _bindings.spine_skeleton_data_result_get_error(result).cast(); + final message = error.toDartString(); + _bindings.spine_skeleton_data_result_dispose(result); + throw Exception("Couldn't load skeleton data: $message"); + } + var data = SkeletonData._(_bindings.spine_skeleton_data_result_get_data(result)); + _bindings.spine_skeleton_data_result_dispose(result); + return data; + } + + /// Loads a [SkeletonData] from the [binary] skeleton data, using the provided [atlas] to resolve attachment + /// images. + /// + /// Throws an [Exception] in case the skeleton data could not be loaded. + static SkeletonData fromBinary(Atlas atlas, Uint8List binary) { + final Pointer binaryNative = _allocator.allocate(binary.lengthInBytes); + binaryNative.asTypedList(binary.lengthInBytes).setAll(0, binary); + final result = _bindings.spine_skeleton_data_load_binary(atlas._atlas, binaryNative.cast(), binary.lengthInBytes); + _allocator.free(binaryNative); + if (_bindings.spine_skeleton_data_result_get_error(result).address != nullptr.address) { + final Pointer error = _bindings.spine_skeleton_data_result_get_error(result).cast(); + final message = error.toDartString(); + _bindings.spine_skeleton_data_result_dispose(result); + throw Exception("Couldn't load skeleton data: $message"); + } + var data = SkeletonData._(_bindings.spine_skeleton_data_result_get_data(result)); + _bindings.spine_skeleton_data_result_dispose(result); + return data; + } + + /// Loads a [SkeletonData] from the file [skeletonFile] in the root bundle or the optionally provided [bundle]. + /// Uses the provided [atlas] to resolve attachment images. + /// + /// Throws an [Exception] in case the skeleton data could not be loaded. + static Future fromAsset(Atlas atlas, String skeletonFile, {AssetBundle? bundle}) async { + bundle ??= rootBundle; + if (skeletonFile.endsWith(".json")) { + return fromJson(atlas, await bundle.loadString(skeletonFile)); + } else { + return fromBinary(atlas, (await bundle.load(skeletonFile)).buffer.asUint8List()); + } + } + + /// Loads a [SkeletonData] from the file [skeletonFile]. Uses the provided [atlas] to resolve attachment images. + /// + /// Throws an [Exception] in case the skeleton data could not be loaded. + static Future fromFile(Atlas atlas, String skeletonFile) async { + if (skeletonFile.endsWith(".json")) { + return fromJson(atlas, convert.utf8.decode(await File(skeletonFile).readAsBytes())); + } else { + return fromBinary(atlas, await File(skeletonFile).readAsBytes()); + } + } + + /// Loads a [SkeletonData] from the URL [skeletonURL]. Uses the provided [atlas] to resolve attachment images. + /// + /// Throws an [Exception] in case the skeleton data could not be loaded. + static Future fromHttp(Atlas atlas, String skeletonURL) async { + if (skeletonURL.endsWith(".json")) { + return fromJson(atlas, convert.utf8.decode((await http.get(Uri.parse(skeletonURL))).bodyBytes)); + } else { + return fromBinary(atlas, (await http.get(Uri.parse(skeletonURL))).bodyBytes); + } + } + + /// The skeleton's bones, sorted parent first. The root bone is always the first bone. + List getBones() { + final List bones = []; + final numBones = _bindings.spine_skeleton_data_get_num_bones(_data); + final nativeBones = _bindings.spine_skeleton_data_get_bones(_data); + for (int i = 0; i < numBones; i++) { + bones.add(BoneData._(nativeBones[i])); + } + return bones; + } + + /// Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it multiple times. + BoneData? findBone(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final bone = _bindings.spine_skeleton_data_find_bone(_data, nativeName.cast()); + _allocator.free(nativeName); + if (bone.address == nullptr.address) return null; + return BoneData._(bone); + } + + /// The skeleton's slots. + List getSlots() { + final List slots = []; + final numSlots = _bindings.spine_skeleton_data_get_num_slots(_data); + final nativeSlots = _bindings.spine_skeleton_data_get_slots(_data); + for (int i = 0; i < numSlots; i++) { + slots.add(SlotData._(nativeSlots[i])); + } + return slots; + } + + /// Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it multiple times. + SlotData? findSlot(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final slot = _bindings.spine_skeleton_data_find_slot(_data, nativeName.cast()); + _allocator.free(nativeName); + if (slot.address == nullptr.address) return null; + return SlotData._(slot); + } + + /// All skins, including the default skin. + List getSkins() { + final List skins = []; + final numSkins = _bindings.spine_skeleton_data_get_num_skins(_data); + final nativeSkins = _bindings.spine_skeleton_data_get_skins(_data); + for (int i = 0; i < numSkins; i++) { + skins.add(Skin._(nativeSkins[i])); + } + return skins; + } + + /// The skeleton's default skin. By default this skin contains all attachments that were not in a skin in Spine. + Skin? getDefaultSkin() { + final skin = _bindings.spine_skeleton_data_get_default_skin(_data); + if (skin.address == nullptr.address) return null; + return Skin._(skin); + } + + void setDefaultSkin(Skin? skin) { + if (skin == null) { + _bindings.spine_skeleton_data_set_default_skin(_data, nullptr); + } else { + _bindings.spine_skeleton_data_set_default_skin(_data, skin._skin); + } + } + + /// Finds a skin by comparing each skin's name. It is more efficient to cache the results of this method than to call it + /// multiple times. + Skin? findSkin(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final skin = _bindings.spine_skeleton_data_find_skin(_data, nativeName.cast()); + _allocator.free(nativeName); + if (skin.address == nullptr.address) return null; + return Skin._(skin); + } + + /// The skeleton's events. + List getEvents() { + final List events = []; + final numEvents = _bindings.spine_skeleton_data_get_num_events(_data); + final nativeEvents = _bindings.spine_skeleton_data_get_events(_data); + for (int i = 0; i < numEvents; i++) { + events.add(EventData._(nativeEvents[i])); + } + return events; + } + + /// Finds an event by comparing each events's name. It is more efficient to cache the results of this method than to call it + /// multiple times. + EventData? findEvent(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final event = _bindings.spine_skeleton_data_find_event(_data, nativeName.cast()); + _allocator.free(nativeName); + if (event.address == nullptr.address) return null; + return EventData._(event); + } + + /// The skeleton's animations. + List getAnimations() { + final List events = []; + final numAnimation = _bindings.spine_skeleton_data_get_num_animations(_data); + final nativeAnimations = _bindings.spine_skeleton_data_get_animations(_data); + for (int i = 0; i < numAnimation; i++) { + events.add(Animation._(nativeAnimations[i])); + } + return events; + } + + /// Finds an animation by comparing each animation's name. It is more efficient to cache the results of this method than to + /// call it multiple times. + Animation? findAnimation(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final animation = _bindings.spine_skeleton_data_find_animation(_data, nativeName.cast()); + _allocator.free(nativeName); + if (animation.address == nullptr.address) return null; + return Animation._(animation); + } + + /// The skeleton's IK constraints. + List getIkConstraints() { + final List constraints = []; + final numConstraints = _bindings.spine_skeleton_data_get_num_ik_constraints(_data); + final nativeConstraints = _bindings.spine_skeleton_data_get_ik_constraints(_data); + for (int i = 0; i < numConstraints; i++) { + constraints.add(IkConstraintData._(nativeConstraints[i])); + } + return constraints; + } + + /// Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method + /// than to call it multiple times. + IkConstraintData? findIkConstraint(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final constraint = _bindings.spine_skeleton_data_find_ik_constraint(_data, nativeName.cast()); + _allocator.free(nativeName); + if (constraint.address == nullptr.address) return null; + return IkConstraintData._(constraint); + } + + /// The skeleton's transform constraints. + List getTransformConstraints() { + final List constraints = []; + final numConstraints = _bindings.spine_skeleton_data_get_num_transform_constraints(_data); + final nativeConstraints = _bindings.spine_skeleton_data_get_transform_constraints(_data); + for (int i = 0; i < numConstraints; i++) { + constraints.add(TransformConstraint._(nativeConstraints[i].cast())); + } + return constraints; + } + + /// Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of + /// this method than to call it multiple times. + TransformConstraintData? findTransformConstraint(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final constraint = _bindings.spine_skeleton_data_find_transform_constraint(_data, nativeName.cast()); + _allocator.free(nativeName); + if (constraint.address == nullptr.address) return null; + return TransformConstraintData._(constraint); + } + + /// The skeleton's path constraints. + List getPathConstraints() { + final List constraints = []; + final numConstraints = _bindings.spine_skeleton_data_get_num_path_constraints(_data); + final nativeConstraints = _bindings.spine_skeleton_data_get_path_constraints(_data); + for (int i = 0; i < numConstraints; i++) { + constraints.add(PathConstraintData._(nativeConstraints[i])); + } + return constraints; + } + + /// Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method + /// than to call it multiple times. + PathConstraintData? findPathConstraint(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final constraint = _bindings.spine_skeleton_data_find_path_constraint(_data, nativeName.cast()); + _allocator.free(nativeName); + if (constraint.address == nullptr.address) return null; + return PathConstraintData._(constraint); + } + + /// The skeleton's name, which by default is the name of the skeleton data file when possible, or null when a name hasn't been + /// set. + String? getName() { + Pointer name = _bindings.spine_skeleton_data_get_name(_data).cast(); + if (name.address == nullptr.address) return null; + return name.toDartString(); + } + + /// The X coordinate of the skeleton's axis aligned bounding box in the setup pose. + double getX() { + return _bindings.spine_skeleton_data_get_x(_data); + } + + void setX(double x) { + _bindings.spine_skeleton_data_set_x(_data, x); + } + + /// The Y coordinate of the skeleton's axis aligned bounding box in the setup pose. + double getY() { + return _bindings.spine_skeleton_data_get_y(_data); + } + + void setY(double y) { + _bindings.spine_skeleton_data_set_x(_data, y); + } + + /// The width of the skeleton's axis aligned bounding box in the setup pose. + double getWidth() { + return _bindings.spine_skeleton_data_get_width(_data); + } + + void setWidth(double width) { + _bindings.spine_skeleton_data_set_width(_data, width); + } + + /// The height of the skeleton's axis aligned bounding box in the setup pose. + double getHeight() { + return _bindings.spine_skeleton_data_get_height(_data); + } + + void setHeight(double height) { + _bindings.spine_skeleton_data_set_height(_data, height); + } + + /// The Spine version used to export the skeleton data. + String? getVersion() { + Pointer name = _bindings.spine_skeleton_data_get_version(_data).cast(); + if (name.address == nullptr.address) return null; + return name.toDartString(); + } + + /// The skeleton data hash. This value will change if any of the skeleton data has changed. + String? getHash() { + Pointer name = _bindings.spine_skeleton_data_get_hash(_data).cast(); + if (name.address == nullptr.address) return null; + return name.toDartString(); + } + + /// The path to the images directory as defined in Spine, or null if nonessential data was not exported. + String? getImagesPath() { + Pointer name = _bindings.spine_skeleton_data_get_images_path(_data).cast(); + if (name.address == nullptr.address) return null; + return name.toDartString(); + } + + /// The path to the audio directory as defined in Spine, or null if nonessential data was not exported. + String? getAudioPath() { + Pointer name = _bindings.spine_skeleton_data_get_audio_path(_data).cast(); + if (name.address == nullptr.address) return null; + return name.toDartString(); + } + + /// The dopesheet FPS in Spine, or zero if nonessential data was not exported. + double getFps() { + return _bindings.spine_skeleton_data_get_fps(_data); + } + + /// Disposes the (native) resources of this skeleton data. The skeleton data can no longer be + /// used after calling this function. Only the first call to this method will + /// have an effect. Subsequent calls are ignored. + void dispose() { + if (_disposed) return; + _disposed = true; + _bindings.spine_skeleton_data_dispose(_data); + } +} + +/// Determines how images are blended with existing pixels when drawn. See [Blending](http://esotericsoftware.com/spine-slots#Blending) in +/// the Spine User Guide. +enum BlendMode { + normal(0), + additive(1), + multiply(2), + screen(3); + + final int value; + + const BlendMode(this.value); +} + +/// Determines how a bone inherits world transforms from parent bones. See [Transform inheritance](esotericsoftware.com/spine-bones#Transform-inheritance) +/// in the Spine User Guide. +enum TransformMode { + normal(0), + onlyTranslation(1), + noRotationOrReflection(2), + noScale(3), + noScaleOrReflection(4); + + final int value; + + const TransformMode(this.value); +} + +/// Controls how the first bone is positioned along the path. +/// +/// See [Position mode](http://esotericsoftware.com/spine-path-constraints#Position-mode) in the Spine User Guide. +enum PositionMode { + fixed(0), + percent(1); + + final int value; + + const PositionMode(this.value); +} + +/// Controls how bones after the first bone are positioned along the path. +/// +/// See [Spacing mode](http://esotericsoftware.com/spine-path-constraints#Spacing-mode) in the Spine User Guide. +enum SpacingMode { + length(0), + fixed(1), + percent(2), + proportional(3); + + final int value; + + const SpacingMode(this.value); +} + +/// Controls how bones are rotated, translated, and scaled to match the path. +/// +/// See [Rotate mode](http://esotericsoftware.com/spine-path-constraints#Rotate-mode) in the Spine User Guide. +enum RotateMode { + tangent(0), + chain(1), + chainScale(2); + + final int value; + + const RotateMode(this.value); +} + +/// Stores the setup pose for a [Bone]. +class BoneData { + final spine_bone_data _data; + + BoneData._(this._data); + + /// The index of the bone in [Skeleton.getBones]. + int getIndex() { + return _bindings.spine_bone_data_get_index(_data); + } + + /// The name of the bone, which is unique across all bones in the skeleton. + String getName() { + Pointer name = _bindings.spine_bone_data_get_name(_data).cast(); + return name.toDartString(); + } + + /// The parent bone or `null` if this is the root bone. + BoneData? getParent() { + final parent = _bindings.spine_bone_data_get_parent(_data); + if (parent.address == nullptr.address) return null; + return BoneData._(parent); + } + + /// The bone's length. + double getLength() { + return _bindings.spine_bone_data_get_length(_data); + } + + void setLength(double length) { + _bindings.spine_bone_data_set_length(_data, length); + } + + /// The local x translation. + double getX() { + return _bindings.spine_bone_data_get_x(_data); + } + + void setX(double x) { + _bindings.spine_bone_data_set_x(_data, x); + } + + /// The local y translation. + double getY() { + return _bindings.spine_bone_data_get_y(_data); + } + + void setY(double y) { + _bindings.spine_bone_data_set_y(_data, y); + } + + /// The local rotation in degrees. + double getRotation() { + return _bindings.spine_bone_data_get_rotation(_data); + } + + void setRotation(double rotation) { + _bindings.spine_bone_data_set_rotation(_data, rotation); + } + + /// The local scaleX. + double getScaleX() { + return _bindings.spine_bone_data_get_scale_x(_data); + } + + void setScaleX(double scaleX) { + _bindings.spine_bone_data_set_scale_x(_data, scaleX); + } + + /// The local scaleY. + double getScaleY() { + return _bindings.spine_bone_data_get_scale_y(_data); + } + + void setScaleY(double scaleY) { + _bindings.spine_bone_data_set_scale_y(_data, scaleY); + } + + /// The local shearX. + double getShearX() { + return _bindings.spine_bone_data_get_shear_x(_data); + } + + void setShearX(double shearX) { + _bindings.spine_bone_data_set_shear_x(_data, shearX); + } + + /// The local shearY. + double getShearY() { + return _bindings.spine_bone_data_get_shear_y(_data); + } + + void setShearY(double shearY) { + _bindings.spine_bone_data_set_shear_y(_data, shearY); + } + + /// The [TransformMode] for how parent world transforms affect this bone. + TransformMode getTransformMode() { + final nativeMode = _bindings.spine_bone_data_get_transform_mode(_data); + return TransformMode.values[nativeMode]; + } + + void setTransformMode(TransformMode mode) { + _bindings.spine_bone_data_set_transform_mode(_data, mode.value); + } + + /// When true, [Skeleton.updateWorldTransform] only updates this bone if the [Skeleton.getSkin] contains this bone. + /// + /// See [Skin.getBones]. + bool isSkinRequired() { + return _bindings.spine_bone_data_is_skin_required(_data) == -1; + } + + void setIsSkinRequired(bool isSkinRequired) { + _bindings.spine_bone_data_set_is_skin_required(_data, isSkinRequired ? -1 : 0); + } + + /// The [Color] of the bone as it was in Spine, or a default color if nonessential data was not exported. Bones are not usually + /// rendered at runtime. + Color getColor() { + final color = _bindings.spine_bone_data_get_color(_data); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_bone_data_set_color(_data, r, g, b, a); + } + + @override + String toString() { + return getName(); + } +} + +/// Stores a bone's current pose. +/// +/// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a +/// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a +/// constraint or application code modifies the world transform after it was computed from the local transform. +class Bone { + final spine_bone _bone; + + Bone._(this._bone); + + /// Assume y-axis pointing down for all calculations. + static void setIsYDown(bool isYDown) { + _bindings.spine_bone_set_is_y_down(isYDown ? -1 : 0); + } + + static bool getIsYDown() { + return _bindings.spine_bone_get_is_y_down() == 1; + } + + /// Computes the world transform using the parent bone and this bone's local applied transform. + void update() { + _bindings.spine_bone_update(_bone); + } + + /// Computes the world transform using the parent bone and this bone's local transform. + /// + /// See [updateWorldTransformWith]. + void updateWorldTransform() { + _bindings.spine_bone_update_world_transform(_bone); + } + + /// Computes the world transform using the parent bone and the specified local transform. The applied transform is set to the + /// specified local transform. Child bones are not updated. + /// + /// See [World transform](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + /// Runtimes Guide. + void updateWorldTransformWith(double x, double y, double rotation, double scaleX, double scaleY, double shearX, double shearY) { + _bindings.spine_bone_update_world_transform_with(_bone, x, y, rotation, scaleX, scaleY, shearX, shearY); + } + + /// Computes the applied transform values from the world transform. + /// + /// If the world transform is modified (by a constraint, [rotateWorld], etc) then this method should be called so + /// the applied transform matches the world transform. The applied transform may be needed by other code (eg to apply another + /// constraint). + /// + /// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The applied transform after + /// calling this method is equivalent to the local transform used to compute the world transform, but may not be identical. + void updateAppliedTransform() { + _bindings.spine_bone_update_applied_transform(_bone); + } + + /// Sets this bone's local transform to the setup pose. + void setToSetupPose() { + _bindings.spine_bone_set_to_setup_pose(_bone); + } + + /// Transforms a point from world coordinates to the bone's local coordinates. + Vec2 worldToLocal(double worldX, double worldY) { + final local = _bindings.spine_bone_world_to_local(_bone, worldX, worldY); + final result = Vec2(_bindings.spine_vector_get_x(local), _bindings.spine_vector_get_y(local)); + _allocator.free(local); + return result; + } + + /// Transforms a point from the bone's local coordinates to world coordinates. + Vec2 localToWorld(double localX, double localY) { + final world = _bindings.spine_bone_local_to_world(_bone, localX, localY); + final result = Vec2(_bindings.spine_vector_get_x(world), _bindings.spine_vector_get_y(world)); + _allocator.free(world); + return result; + } + + /// Transforms a world rotation to a local rotation. + double worldToLocalRotation(double worldRotation) { + return _bindings.spine_bone_world_to_local_rotation(_bone, worldRotation); + } + + /// Transforms a local rotation to a world rotation. + double localToWorldRotation(double localRotation) { + return _bindings.spine_bone_local_to_world_rotation(_bone, localRotation); + } + + /// Rotates the world transform the specified amount. + /// + /// After changes are made to the world transform, [updateAppliedTransform] should be called and [update] will + /// need to be called on any child bones, recursively. + void rotateWorld(double degrees) { + _bindings.spine_bone_rotate_world(_bone, degrees); + } + + double getWorldToLocalRotationX() { + return _bindings.spine_bone_get_world_rotation_x(_bone); + } + + double getWorldToLocalRotationY() { + return _bindings.spine_bone_get_world_to_local_rotation_y(_bone); + } + + /// The bone's setup pose data. + BoneData getData() { + return BoneData._(_bindings.spine_bone_get_data(_bone)); + } + + /// The skeleton this bone belongs to. + Skeleton getSkeleton() { + return Skeleton._(_bindings.spine_bone_get_skeleton(_bone)); + } + + /// The parent bone, or null if this is the root bone. + Bone? getParent() { + final parent = _bindings.spine_bone_get_parent(_bone); + if (parent.address == nullptr.address) return null; + return Bone._(parent); + } + + /// The immediate children of this bone. + List getChildren() { + List children = []; + final numChildren = _bindings.spine_bone_get_num_children(_bone); + final nativeChildren = _bindings.spine_bone_get_children(_bone); + for (int i = 0; i < numChildren; i++) { + children.add(Bone._(nativeChildren[i])); + } + return children; + } + + /// The local x translation. + double getX() { + return _bindings.spine_bone_get_x(_bone); + } + + void setX(double x) { + _bindings.spine_bone_set_x(_bone, x); + } + + /// The local y translation. + double getY() { + return _bindings.spine_bone_get_y(_bone); + } + + void setY(double y) { + _bindings.spine_bone_set_y(_bone, y); + } + + /// The local rotation in degrees, counter clockwise. + double getRotation() { + return _bindings.spine_bone_get_rotation(_bone); + } + + void setRotation(double rotation) { + _bindings.spine_bone_set_rotation(_bone, rotation); + } + + /// The local scaleX. + double getScaleX() { + return _bindings.spine_bone_get_scale_x(_bone); + } + + void setScaleX(double scaleX) { + _bindings.spine_bone_set_scale_x(_bone, scaleX); + } + + /// The local scaleY. + double getScaleY() { + return _bindings.spine_bone_get_scale_y(_bone); + } + + void setScaleY(double scaleY) { + _bindings.spine_bone_set_scale_y(_bone, scaleY); + } + + /// The local shearX. + double getShearX() { + return _bindings.spine_bone_get_shear_x(_bone); + } + + void setShearX(double shearX) { + _bindings.spine_bone_set_shear_x(_bone, shearX); + } + + /// The local shearY. + double getShearY() { + return _bindings.spine_bone_get_shear_y(_bone); + } + + void setShearY(double shearY) { + _bindings.spine_bone_set_shear_y(_bone, shearY); + } + + /// The applied local x translation. + double getAX() { + return _bindings.spine_bone_get_a_x(_bone); + } + + void setAX(double x) { + _bindings.spine_bone_set_a_x(_bone, x); + } + + /// The applied local y translation. + double getAY() { + return _bindings.spine_bone_get_a_y(_bone); + } + + void setAY(double y) { + _bindings.spine_bone_set_a_y(_bone, y); + } + + /// The applied local rotation in degrees, counter clockwise. + double getAppliedRotation() { + return _bindings.spine_bone_get_applied_rotation(_bone); + } + + void setAppliedRotation(double rotation) { + _bindings.spine_bone_set_applied_rotation(_bone, rotation); + } + + /// The applied local scaleX. + double getAScaleX() { + return _bindings.spine_bone_get_a_scale_x(_bone); + } + + void setAScaleX(double scaleX) { + _bindings.spine_bone_set_a_scale_x(_bone, scaleX); + } + + /// The applied local scaleY. + double getAScaleY() { + return _bindings.spine_bone_get_a_scale_y(_bone); + } + + void setAScaleY(double scaleY) { + _bindings.spine_bone_set_a_scale_y(_bone, scaleY); + } + + /// The applied local shearX. + double getAShearX() { + return _bindings.spine_bone_get_a_shear_x(_bone); + } + + void setAShearX(double shearX) { + _bindings.spine_bone_set_a_shear_x(_bone, shearX); + } + + /// The applied local shearY. + double getAShearY() { + return _bindings.spine_bone_get_a_shear_y(_bone); + } + + void setAShearY(double shearY) { + _bindings.spine_bone_set_a_shear_y(_bone, shearY); + } + + /// Part of the world transform matrix for the X axis. If changed, [updateAppliedTransform] should be called. + double getA() { + return _bindings.spine_bone_get_a(_bone); + } + + void setA(double a) { + _bindings.spine_bone_set_a(_bone, a); + } + + /// Part of the world transform matrix for the Y axis. If changed, [updateAppliedTransform] should be called. + double getB() { + return _bindings.spine_bone_get_b(_bone); + } + + void setB(double b) { + _bindings.spine_bone_set_b(_bone, b); + } + + /// Part of the world transform matrix for the X axis. If changed, [updateAppliedTransform] should be called. + double getC() { + return _bindings.spine_bone_get_c(_bone); + } + + void setC(double c) { + _bindings.spine_bone_set_c(_bone, c); + } + + /// Part of the world transform matrix for the Y axis. If changed, [updateAppliedTransform] should be called. + double getD() { + return _bindings.spine_bone_get_d(_bone); + } + + void setD(double d) { + _bindings.spine_bone_set_a(_bone, d); + } + + /// The world X position. If changed, [updateAppliedTransform] should be called. + double getWorldX() { + return _bindings.spine_bone_get_world_x(_bone); + } + + void setWorldX(double worldX) { + _bindings.spine_bone_set_world_x(_bone, worldX); + } + + /// The world Y position. If changed, [updateAppliedTransform] should be called. + double getWorldY() { + return _bindings.spine_bone_get_world_y(_bone); + } + + void setWorldY(double worldY) { + _bindings.spine_bone_set_world_y(_bone, worldY); + } + + /// The world rotation for the X axis, calculated using [getA] and [getC]. + double getWorldRotationX() { + return _bindings.spine_bone_get_world_rotation_x(_bone); + } + + /// The world rotation for the Y axis, calculated using [getB] and [getD]. + double getWorldRotationY() { + return _bindings.spine_bone_get_world_rotation_y(_bone); + } + + /// The magnitude (always positive) of the world scale X, calculated using [getA] and [getC]. + double getWorldScaleX() { + return _bindings.spine_bone_get_world_scale_x(_bone); + } + + /// The magnitude (always positive) of the world scale Y, calculated using [getB] and [getD]. + double getWorldScaleY() { + return _bindings.spine_bone_get_world_scale_y(_bone); + } + + /// Returns false when the bone has not been computed because [BoneData.getSkinRequired] is true and the + /// active skin (see [Skeleton.getSkin]) does not contain this bone (see [Skin.getBones]). + bool isActive() { + return _bindings.spine_bone_get_is_active(_bone) == -1; + } + + void setIsActive(bool isActive) { + _bindings.spine_bone_set_is_active(_bone, isActive ? -1 : 0); + } +} + +/// Stores the setup pose for a [Slot]. +class SlotData { + final spine_slot_data _data; + + SlotData._(this._data); + + /// The index of the slot in [Skeleton.getSlots]. + int getIndex() { + return _bindings.spine_slot_data_get_index(_data); + } + + /// The name of the slot, which is unique across all slots in the skeleton. + String getName() { + final Pointer value = _bindings.spine_slot_data_get_name(_data).cast(); + return value.toDartString(); + } + + /// The bone this slot belongs to. + BoneData getBoneData() { + return BoneData._(_bindings.spine_slot_data_get_bone_data(_data)); + } + + /// The [Color] used to tint the slot's attachment. If [hasDarkColor] is true, this is used as the light color for two + /// color tinting. + Color getColor() { + final color = _bindings.spine_slot_data_get_color(_data); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_slot_data_set_color(_data, r, g, b, a); + } + + /// The dark color used to tint the slot's attachment for two color tinting, if [hasDarkColor] is true. The dark + /// color's alpha is not used. + Color getDarkColor() { + final color = _bindings.spine_slot_data_get_dark_color(_data); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setDarkColor(double r, double g, double b, double a) { + _bindings.spine_slot_data_set_dark_color(_data, r, g, b, a); + } + + /// Returns whether this slot has a dark color set for two color tinting. + bool hasDarkColor() { + return _bindings.spine_slot_data_has_dark_color(_data) == -1; + } + + void setHasDarkColor(bool hasDarkColor) { + _bindings.spine_slot_data_set_has_dark_color(_data, hasDarkColor ? -1 : 0); + } + + /// The name of the attachment that is visible for this slot in the setup pose, or null if no attachment is visible. + String getAttachmentName() { + final Pointer value = _bindings.spine_slot_data_get_attachment_name(_data).cast(); + return value.toDartString(); + } + + void setAttachmentName(String attachmentName) { + final nativeName = attachmentName.toNativeUtf8(allocator: _allocator); + _bindings.spine_slot_data_set_attachment_name(_data, nativeName.cast()); + _allocator.free(nativeName); + } + + /// The [BlendMode] for drawing the slot's attachment. + BlendMode getBlendMode() { + return BlendMode.values[_bindings.spine_slot_data_get_blend_mode(_data)]; + } + + void setBlendMode(BlendMode mode) { + _bindings.spine_slot_data_set_blend_mode(_data, mode.value); + } + + @override + String toString() { + return getName(); + } +} + +/// Stores a slot's current pose. Slots organize attachments for [Skeleton.getDrawOrder] purposes and provide a place to store +/// state for an attachment. State cannot be stored in an attachment itself because attachments are stateless and may be shared +/// across multiple skeletons. +class Slot { + final spine_slot _slot; + + Slot._(this._slot); + + /// Sets this slot to the setup pose. + void setToSetupPose() { + _bindings.spine_slot_set_to_setup_pose(_slot); + } + + /// The slot's setup pose data. + SlotData getData() { + return SlotData._(_bindings.spine_slot_get_data(_slot)); + } + + /// The bone this slot belongs to. + Bone getBone() { + return Bone._(_bindings.spine_slot_get_bone(_slot)); + } + + /// The skeleton this slot belongs to. + Skeleton getSkeleton() { + return Skeleton._(_bindings.spine_slot_get_skeleton(_slot)); + } + + /// The color used to tint the slot's attachment. If [hasDarkColor] is true, this is used as the light color for two + /// color tinting. + Color getColor() { + final color = _bindings.spine_slot_get_color(_slot); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(Color color) { + _bindings.spine_slot_set_color(_slot, color.r, color.g, color.b, color.a); + } + + /// The dark color used to tint the slot's attachment for two color tinting, if [hasDarkColor] is true. The dark + /// color's alpha is not used. + Color getDarkColor() { + final color = _bindings.spine_slot_get_dark_color(_slot); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setDarkColor(Color color) { + _bindings.spine_slot_set_dark_color(_slot, color.r, color.g, color.b, color.a); + } + + /// Returns whether this slot has a dark color set for two color tinting. + bool hasDarkColor() { + return _bindings.spine_slot_has_dark_color(_slot) == -1; + } + + /// The current attachment for the slot, or null if the slot has no attachment. + Attachment? getAttachment() { + final attachment = _bindings.spine_slot_get_attachment(_slot); + if (attachment.address == nullptr.address) return null; + return Attachment._toSubclass(attachment); + } + + void setAttachment(Attachment? attachment) { + _bindings.spine_slot_set_attachment(_slot, attachment != null ? attachment._attachment.cast() : nullptr); + } + + @override + String toString() { + return getData().getName(); + } + + /// The index of the texture region to display when the slot's attachment has a [Sequence]. -1 represents the + /// [Sequence.getSetupIndex]. + int getSequenceIndex() { + return _bindings.spine_slot_get_sequence_index(_slot); + } + + void setSequenceIndex(int sequenceIndex) { + _bindings.spine_slot_set_sequence_index(_slot, sequenceIndex); + } +} + +/// A region within a texture, given in normalized texture coordinates of the top left ([getU], [getV]) and +/// bottom left ([getU2], [getV2]) corner of the region within the texture. +class TextureRegion { + final spine_texture_region _region; + + TextureRegion._(this._region); + + Pointer getTexture() { + return _bindings.spine_texture_region_get_texture(_region); + } + + void setTexture(Pointer texture) { + _bindings.spine_texture_region_set_texture(_region, texture); + } + + double getU() { + return _bindings.spine_texture_region_get_u(_region); + } + + void setU(double u) { + _bindings.spine_texture_region_set_u(_region, u); + } + + double getV() { + return _bindings.spine_texture_region_get_v(_region); + } + + void setV(double v) { + _bindings.spine_texture_region_set_v(_region, v); + } + + double getU2() { + return _bindings.spine_texture_region_get_u2(_region); + } + + void setU2(double u2) { + _bindings.spine_texture_region_set_u2(_region, u2); + } + + double getV2() { + return _bindings.spine_texture_region_get_v2(_region); + } + + void setV2(double v2) { + _bindings.spine_texture_region_set_v2(_region, v2); + } + + int getDegrees() { + return _bindings.spine_texture_region_get_degrees(_region); + } + + void setDegrees(int degrees) { + _bindings.spine_texture_region_set_degrees(_region, degrees); + } + + double getOffsetX() { + return _bindings.spine_texture_region_get_offset_x(_region); + } + + void setOffsetX(double offsetX) { + _bindings.spine_texture_region_set_offset_x(_region, offsetX); + } + + double getOffsetY() { + return _bindings.spine_texture_region_get_offset_x(_region); + } + + void setOffsetY(double offsetX) { + _bindings.spine_texture_region_set_offset_x(_region, offsetX); + } + + int getWidth() { + return _bindings.spine_texture_region_get_width(_region); + } + + void setWidth(int width) { + _bindings.spine_texture_region_set_width(_region, width); + } + + int getHeight() { + return _bindings.spine_texture_region_get_height(_region); + } + + void setHeight(int height) { + _bindings.spine_texture_region_set_height(_region, height); + } + + int getOriginalWidth() { + return _bindings.spine_texture_region_get_original_width(_region); + } + + void setOriginalWidth(int originalWidth) { + _bindings.spine_texture_region_set_original_width(_region, originalWidth); + } + + int getOriginalHeight() { + return _bindings.spine_texture_region_get_original_height(_region); + } + + void setOriginalHeight(int originalHeight) { + _bindings.spine_texture_region_set_original_height(_region, originalHeight); + } +} + +/// Stores a sequence of [TextureRegion] instances that will switched through when set on an attachment. +class Sequence { + final spine_sequence _sequence; + + Sequence._(this._sequence); + + void apply(Slot slot, Attachment attachment) { + _bindings.spine_sequence_apply(_sequence, slot._slot, attachment._attachment.cast()); + } + + String getPath(String basePath, int index) { + final nativeBasePath = basePath.toNativeUtf8(allocator: _allocator); + final Pointer path = _bindings.spine_sequence_get_path(_sequence, nativeBasePath.cast(), index).cast(); + final result = path.toDartString(); + _allocator.free(nativeBasePath); + _allocator.free(path); + return result; + } + + int getId() { + return _bindings.spine_sequence_get_id(_sequence); + } + + void setId(int id) { + _bindings.spine_sequence_set_id(_sequence, id); + } + + int getStart() { + return _bindings.spine_sequence_get_start(_sequence); + } + + void setStart(int start) { + _bindings.spine_sequence_set_start(_sequence, start); + } + + int getDigits() { + return _bindings.spine_sequence_get_digits(_sequence); + } + + void setDigits(int digits) { + _bindings.spine_sequence_set_digits(_sequence, digits); + } + + int getSetupIndex() { + return _bindings.spine_sequence_get_setup_index(_sequence); + } + + void setSetupIndex(int setupIndex) { + _bindings.spine_sequence_set_setup_index(_sequence, setupIndex); + } + + List getRegions() { + List result = []; + final num = _bindings.spine_sequence_get_num_regions(_sequence); + final nativeRegions = _bindings.spine_sequence_get_regions(_sequence); + for (int i = 0; i < num; i++) { + result.add(TextureRegion._(nativeRegions[i])); + } + return result; + } +} + +/// Attachment types. +enum AttachmentType { + region(0), + mesh(1), + clipping(2), + boundingBox(3), + path(4), + point(5); + + final int value; + + const AttachmentType(this.value); +} + +/// The base class for all attachments. +abstract class Attachment { + final T _attachment; + + Attachment._(this._attachment); + + /// The attachment's name. + String getName() { + Pointer name = _bindings.spine_attachment_get_name(_attachment.cast()).cast(); + return name.toString(); + } + + /// The attachment's type. + AttachmentType getType() { + final type = _bindings.spine_attachment_get_type(_attachment.cast()); + return AttachmentType.values[type]; + } + + static Attachment _toSubclass(spine_attachment attachment) { + final type = AttachmentType.values[_bindings.spine_attachment_get_type(attachment)]; + switch (type) { + case AttachmentType.region: + return RegionAttachment._(attachment.cast()); + case AttachmentType.mesh: + return MeshAttachment._(attachment.cast()); + case AttachmentType.clipping: + return ClippingAttachment._(attachment.cast()); + case AttachmentType.boundingBox: + return BoundingBoxAttachment._(attachment.cast()); + case AttachmentType.path: + return PathAttachment._(attachment.cast()); + case AttachmentType.point: + return PointAttachment._(attachment.cast()); + } + } + + /// Returns a copy of the attachment. Copied attachments need to be disposed manually + /// when no longer in use via the [dispose] method. + Attachment copy() { + return _toSubclass(_bindings.spine_attachment_copy(_attachment.cast())); + } + + void dispose() { + _bindings.spine_attachment_dispose(_attachment.cast()); + } +} + +/// An attachment that displays a textured quadrilateral. +/// +/// See [Region attachments](http://esotericsoftware.com/spine-regions) in the Spine User Guide. +class RegionAttachment extends Attachment { + RegionAttachment._(spine_region_attachment attachment) : super._(attachment); + + /// Transforms and returns the attachment's four vertices to world coordinates. If the attachment has a [Sequence], the region may + /// be changed. + /// + /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + /// Runtimes Guide. + List computeWorldVertices(Slot slot) { + Pointer vertices = _allocator.allocate(4 * 8).cast(); + _bindings.spine_region_attachment_compute_world_vertices(_attachment, slot._slot, vertices); + final result = vertices.asTypedList(8).toList(); + _allocator.free(vertices); + return result; + } + + /// The local x translation. + double getX() { + return _bindings.spine_region_attachment_get_x(_attachment); + } + + void setX(double x) { + _bindings.spine_region_attachment_set_x(_attachment, x); + } + + /// The local y translation. + double getY() { + return _bindings.spine_region_attachment_get_y(_attachment); + } + + void setY(double y) { + _bindings.spine_region_attachment_set_y(_attachment, y); + } + + /// The local rotation. + double getRotation() { + return _bindings.spine_region_attachment_get_rotation(_attachment); + } + + void setRotation(double rotation) { + _bindings.spine_region_attachment_set_rotation(_attachment, rotation); + } + + /// The local scaleX. + double getScaleX() { + return _bindings.spine_region_attachment_get_scale_x(_attachment); + } + + void setScaleX(double scaleX) { + _bindings.spine_region_attachment_set_scale_x(_attachment, scaleX); + } + + /// The local scaleY. + double getScaleY() { + return _bindings.spine_region_attachment_get_scale_y(_attachment); + } + + void setScaleY(double scaleY) { + _bindings.spine_region_attachment_set_scale_x(_attachment, scaleY); + } + + /// The width of the region attachment in Spine. + double getWidth() { + return _bindings.spine_region_attachment_get_width(_attachment); + } + + void setWidth(double width) { + _bindings.spine_region_attachment_set_width(_attachment, width); + } + + /// The height of the region attachment in Spine. + double getHeight() { + return _bindings.spine_region_attachment_get_height(_attachment); + } + + void setHeight(double height) { + _bindings.spine_region_attachment_set_height(_attachment, height); + } + + Color getColor() { + final color = _bindings.spine_region_attachment_get_color(_attachment); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_region_attachment_set_color(_attachment, r, g, b, a); + } + + String getPath() { + Pointer path = _bindings.spine_region_attachment_get_path(_attachment).cast(); + return path.toDartString(); + } + + TextureRegion? getRegion() { + final region = _bindings.spine_region_attachment_get_region(_attachment); + if (region.address == nullptr.address) return null; + return TextureRegion._(region); + } + + Sequence? getSequence() { + final sequence = _bindings.spine_region_attachment_get_sequence(_attachment); + if (sequence.address == nullptr.address) return null; + return Sequence._(sequence); + } + + /// For each of the 4 vertices, a pair of `x,y` values that is the local position of the vertex. + /// + /// See [updateRegion]. + Float32List getOffset() { + final num = _bindings.spine_region_attachment_get_num_offset(_attachment); + final offset = _bindings.spine_region_attachment_get_offset(_attachment); + return offset.asTypedList(num); + } + + Float32List getUVs() { + final num = _bindings.spine_region_attachment_get_num_uvs(_attachment); + final offset = _bindings.spine_region_attachment_get_uvs(_attachment); + return offset.asTypedList(num); + } +} + +/// Base class for an attachment with vertices that are transformed by one or more bones and can be deformed by a slot's +/// [Slot.getDeform]. +class VertexAttachment extends Attachment { + VertexAttachment._(T attachment) : super._(attachment); + + /// Transforms and returns the attachment's local [getVertices] to world coordinates. If the slot's [Slot.getDeform] is + /// not empty, it is used to deform the vertices. + + /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + /// Runtimes Guide. + List computeWorldVertices(Slot slot) { + final worldVerticesLength = _bindings.spine_vertex_attachment_get_world_vertices_length(_attachment.cast()); + Pointer vertices = _allocator.allocate(4 * worldVerticesLength).cast(); + _bindings.spine_vertex_attachment_compute_world_vertices(_attachment.cast(), slot._slot, vertices); + final result = vertices.asTypedList(worldVerticesLength).toList(); + _allocator.free(vertices); + return result; + } + + /// The bones which affect the [getVertices]. The array entries are, for each vertex, the number of bones affecting + /// the vertex followed by that many bone indices, which is the index of the bone in [Skeleton.getBones]. Will be null + /// if this attachment has no weights. + Int32List getBones() { + final num = _bindings.spine_vertex_attachment_get_num_bones(_attachment.cast()); + final bones = _bindings.spine_vertex_attachment_get_bones(_attachment.cast()); + return bones.asTypedList(num); + } + + /// The vertex positions in the bone's coordinate system. For a non-weighted attachment, the values are `x,y` + /// entries for each vertex. For a weighted attachment, the values are `x,y,weight` entries for each bone affecting + /// each vertex. + Float32List getVertices() { + final num = _bindings.spine_vertex_attachment_get_num_vertices(_attachment.cast()); + final vertices = _bindings.spine_vertex_attachment_get_vertices(_attachment.cast()); + return vertices.asTypedList(num); + } + + /// Timelines for the timeline attachment are also applied to this attachment. May return `null` if not + /// attachment-specific timelines should be applied. + Attachment? getTimelineAttachment() { + final attachment = _bindings.spine_vertex_attachment_get_timeline_attachment(_attachment.cast()); + if (_attachment.address == nullptr.address) return null; + return Attachment._toSubclass(attachment); + } + + void setTimelineAttachment(Attachment? attachment) { + _bindings.spine_vertex_attachment_set_timeline_attachment( + _attachment.cast(), attachment == null ? nullptr : attachment._attachment.cast()); + } +} + +/// An attachment that displays a textured mesh. A mesh has hull vertices and internal vertices within the hull. Holes are not +/// supported. Each vertex has UVs (texture coordinates) and triangles are used to map an image on to the mesh. +/// +/// See [Mesh attachments](http://esotericsoftware.com/spine-meshes) in the Spine User Guide. +class MeshAttachment extends VertexAttachment { + MeshAttachment._(spine_mesh_attachment attachment) : super._(attachment.cast()); + + /// Calculates texture coordinates returned by [getUVs] using the coordinates returned by [getRegionUVs] and region. Must be called if + /// the region, the region's properties, or the [getRegionUVs] are changed. + void updateRegion() { + _bindings.spine_mesh_attachment_update_region(_attachment); + } + + /// The number of entries at the beginning of {@link #vertices} that make up the mesh hull. + int getHullLength() { + return _bindings.spine_mesh_attachment_get_hull_length(_attachment); + } + + void setHullLength(int hullLength) { + _bindings.spine_mesh_attachment_set_hull_length(_attachment, hullLength); + } + + /// The UV pair for each vertex, normalized within the texture region. + Float32List getRegionUVs() { + final num = _bindings.spine_mesh_attachment_get_num_region_uvs(_attachment); + final uvs = _bindings.spine_mesh_attachment_get_region_uvs(_attachment); + return uvs.asTypedList(num); + } + + /// The UV pair for each vertex, normalized within the entire texture. + /// + /// See [updateRegion]. + Float32List getUVs() { + final num = _bindings.spine_mesh_attachment_get_num_uvs(_attachment); + final uvs = _bindings.spine_mesh_attachment_get_uvs(_attachment); + return uvs.asTypedList(num); + } + + /// Triplets of vertex indices which describe the mesh's triangulation. + Uint16List getTriangles() { + final num = _bindings.spine_mesh_attachment_get_num_triangles(_attachment); + final triangles = _bindings.spine_mesh_attachment_get_triangles(_attachment); + return triangles.asTypedList(num); + } + + Color getColor() { + final color = _bindings.spine_mesh_attachment_get_color(_attachment); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_mesh_attachment_set_color(_attachment, r, g, b, a); + } + + String getPath() { + Pointer path = _bindings.spine_mesh_attachment_get_path(_attachment).cast(); + return path.toDartString(); + } + + TextureRegion? getRegion() { + final region = _bindings.spine_mesh_attachment_get_region(_attachment); + if (region.address == nullptr.address) return null; + return TextureRegion._(region); + } + + Sequence? getSequence() { + final sequence = _bindings.spine_mesh_attachment_get_sequence(_attachment); + if (sequence.address == nullptr.address) return null; + return Sequence._(sequence); + } + + /// The parent mesh if this is a linked mesh, else null. A linked mesh shares the bones, vertices, + /// region UVs, triangles, hull length, edges, width, and height with the + /// parent mesh, but may have a different name or path (and therefore a different texture). + MeshAttachment? getParentMesh() { + final parent = _bindings.spine_mesh_attachment_get_parent_mesh(_attachment); + if (parent.address == nullptr.address) return null; + return MeshAttachment._(parent); + } + + void setParentMesh(MeshAttachment? parentMesh) { + _bindings.spine_mesh_attachment_set_parent_mesh(_attachment, parentMesh == null ? nullptr : parentMesh._attachment); + } + + /// Vertex index pairs describing edges for controlling triangulation, or be null if nonessential data was not exported. Mesh + /// triangles will never cross edges. Triangulation is not performed at runtime. + Uint16List getEdges() { + final num = _bindings.spine_mesh_attachment_get_num_edges(_attachment); + final edges = _bindings.spine_mesh_attachment_get_edges(_attachment); + return edges.asTypedList(num); + } + + /// The width of the mesh's image, or zero if nonessential data was not exported. + double getWidth() { + return _bindings.spine_mesh_attachment_get_width(_attachment); + } + + void setWidth(double width) { + _bindings.spine_mesh_attachment_set_width(_attachment, width); + } + + /// The height of the mesh's image, or zero if nonessential data was not exported. + double getHeight() { + return _bindings.spine_mesh_attachment_get_height(_attachment); + } + + void setHeight(double height) { + _bindings.spine_mesh_attachment_set_height(_attachment, height); + } +} + +/// An attachment with vertices that make up a polygon used for clipping the rendering of other attachments. +class ClippingAttachment extends VertexAttachment { + ClippingAttachment._(spine_clipping_attachment attachment) : super._(attachment.cast()); + + /// Clipping is performed between the clipping attachment's slot and the end slot. If null clipping is done until the end of + /// the skeleton's rendering. + SlotData? getEndSlot() { + final endSlot = _bindings.spine_clipping_attachment_get_end_slot(_attachment); + if (endSlot.address == nullptr.address) return null; + return SlotData._(endSlot); + } + + void setEndSlot(SlotData? endSlot) { + _bindings.spine_clipping_attachment_set_end_slot(_attachment, endSlot == null ? nullptr : endSlot._data); + } + + /// The color of the clipping attachment as it was in Spine, or a default color if nonessential data was not exported. Clipping + /// attachments are not usually rendered at runtime. + Color getColor() { + final color = _bindings.spine_clipping_attachment_get_color(_attachment); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_clipping_attachment_set_color(_attachment, r, g, b, a); + } +} + +/// An attachment with vertices that make up a polygon. Can be used for hit detection, creating physics bodies, spawning particle +/// effects, and more. +/// +/// See [SkeletonBounds] and [Bounding boxes](http://esotericsoftware.com/spine-bounding-boxes) in the Spine User +/// Guide. +class BoundingBoxAttachment extends VertexAttachment { + BoundingBoxAttachment._(spine_bounding_box_attachment attachment) : super._(attachment); + + /// The color of the bounding box as it was in Spine, or a default color if nonessential data was not exported. Bounding boxes + /// are not usually rendered at runtime. + Color getColor() { + final color = _bindings.spine_bounding_box_attachment_get_color(_attachment); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_bounding_box_attachment_set_color(_attachment, r, g, b, a); + } +} + +/// An attachment whose vertices make up a composite Bezier curve. +/// +/// See [PathConstraint] and [Paths](http://esotericsoftware.com/spine-paths) in the Spine User Guide. +class PathAttachment extends VertexAttachment { + PathAttachment._(spine_path_attachment attachment) : super._(attachment); + + /// The lengths along the path in the setup pose from the start of the path to the end of each Bezier curve. + Float32List getLengths() { + final num = _bindings.spine_path_attachment_get_num_lengths(_attachment); + final lengths = _bindings.spine_path_attachment_get_lengths(_attachment); + return lengths.asTypedList(num); + } + + /// If true, the start and end knots are connected. + bool isClosed() { + return _bindings.spine_path_attachment_get_is_closed(_attachment) == -1; + } + + void setIsClosed(bool isClosed) { + _bindings.spine_path_attachment_set_is_closed(_attachment, isClosed ? -1 : 0); + } + + /// If true, additional calculations are performed to make computing positions along the path more accurate and movement along + /// the path have a constant speed. + bool isConstantSpeed() { + return _bindings.spine_path_attachment_get_is_constant_speed(_attachment) == -1; + } + + void setIsConstantSpeed(bool isClosed) { + _bindings.spine_path_attachment_set_is_constant_speed(_attachment, isClosed ? -1 : 0); + } + + /// The color of the path as it was in Spine, or a default color if nonessential data was not exported. Paths are not usually + /// rendered at runtime. + Color getColor() { + final color = _bindings.spine_path_attachment_get_color(_attachment); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_path_attachment_set_color(_attachment, r, g, b, a); + } +} + +/// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be +/// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a +/// skin. +/// +/// See [Point Attachments](http://esotericsoftware.com/spine-point-attachments) in the Spine User Guide. +class PointAttachment extends Attachment { + PointAttachment._(spine_point_attachment attachment) : super._(attachment); + + Vec2 computeWorldPosition(Bone bone) { + final position = _bindings.spine_point_attachment_compute_world_position(_attachment, bone._bone); + final result = Vec2(_bindings.spine_vector_get_x(position), _bindings.spine_vector_get_y(position)); + _allocator.free(position); + return result; + } + + double computeWorldRotation(Bone bone) { + return _bindings.spine_point_attachment_compute_world_rotation(_attachment, bone._bone); + } + + double getX() { + return _bindings.spine_point_attachment_get_x(_attachment); + } + + void setX(double x) { + _bindings.spine_point_attachment_set_x(_attachment, x); + } + + double getY() { + return _bindings.spine_point_attachment_get_y(_attachment); + } + + void setY(double y) { + _bindings.spine_point_attachment_set_y(_attachment, y); + } + + double getRotation() { + return _bindings.spine_point_attachment_get_rotation(_attachment); + } + + void setRotation(double rotation) { + _bindings.spine_point_attachment_set_x(_attachment, rotation); + } + + /// The color of the point attachment as it was in Spine, or a default clor if nonessential data was not exported. Point + /// attachments are not usually rendered at runtime. + Color getColor() { + final color = _bindings.spine_point_attachment_get_color(_attachment); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(double r, double g, double b, double a) { + _bindings.spine_point_attachment_set_color(_attachment, r, g, b, a); + } +} + +/// An entry storing the attachment to be used for a specific slot within [Skin]. +class SkinEntry { + final int slotIndex; + final String name; + final Attachment? attachment; + + SkinEntry(this.slotIndex, this.name, this.attachment); +} + +/// Stores attachments by slot index and attachment name. +/// +/// Skins constructed manually via the `Skin(String name)` constructor must be manually disposed via the [dipose] method if they +/// are no longer used. +/// +/// See [SkeletonData.defaultSkin], [Skeleton.getSkin}, and [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the +/// Spine Runtimes Guide. +class Skin { + late final bool _isCustomSkin; + late final spine_skin _skin; + + Skin._(this._skin) : _isCustomSkin = false; + + /// Constructs a new empty skin using the given [name]. Skins constructed this way must be manually disposed via the [dispose] method + /// if they are no longer used. + Skin(String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + _skin = _bindings.spine_skin_create(nativeName.cast()); + _allocator.free(nativeName); + _isCustomSkin = true; + } + + /// Diposes this skin. + void dispose() { + if (!_isCustomSkin) return; + _bindings.spine_skin_dispose(_skin); + } + + /// Adds an attachment to the skin for the specified slot index and name. + void setAttachment(int slotIndex, String name, Attachment? attachment) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + _bindings.spine_skin_set_attachment(_skin, slotIndex, nativeName.cast(), attachment == null ? nullptr : attachment._attachment.cast()); + _allocator.free(nativeName); + } + + /// Returns the attachment for the specified slot index and name, or null. + Attachment? getAttachment(int slotIndex, String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + final attachment = _bindings.spine_skin_get_attachment(_skin, slotIndex, nativeName.cast()); + _allocator.free(nativeName); + if (attachment.address == nullptr.address) return null; + return Attachment._toSubclass(attachment); + } + + /// Removes the attachment in the skin for the specified slot index and name, if any. + void removeAttachment(int slotIndex, String name) { + final nativeName = name.toNativeUtf8(allocator: _allocator); + _bindings.spine_skin_remove_attachment(_skin, slotIndex, nativeName.cast()); + _allocator.free(nativeName); + } + + /// The skin's name, which is unique across all skins in the skeleton. + String getName() { + Pointer name = _bindings.spine_skin_get_name(_skin).cast(); + return name.toDartString(); + } + + /// Adds all attachments, bones, and constraints from the specified skin to this skin. + void addSkin(Skin other) { + _bindings.spine_skin_add_skin(_skin, other._skin); + } + + /// Returns all entries in this skin. + List getEntries() { + List result = []; + final entries = _bindings.spine_skin_get_entries(_skin); + int numEntries = _bindings.spine_skin_entries_get_num_entries(entries); + for (int i = 0; i < numEntries; i++) { + final entry = _bindings.spine_skin_entries_get_entry(entries, i); + Pointer name = _bindings.spine_skin_entry_get_name(entry).cast(); + result.add(SkinEntry( + _bindings.spine_skin_entry_get_slot_index(entry), + name.toDartString(), + _bindings.spine_skin_entry_get_attachment(entry).address == nullptr.address + ? null + : Attachment._toSubclass(_bindings.spine_skin_entry_get_attachment(entry)))); + } + return result; + } + + List getBones() { + List bones = []; + final numBones = _bindings.spine_skin_get_num_bones(_skin); + final nativeBones = _bindings.spine_skin_get_bones(_skin); + for (int i = 0; i < numBones; i++) { + bones.add(BoneData._(nativeBones[i])); + } + return bones; + } + + List getConstraints() { + List constraints = []; + final numConstraints = _bindings.spine_skin_get_num_constraints(_skin); + final nativeConstraints = _bindings.spine_skin_get_constraints(_skin); + for (int i = 0; i < numConstraints; i++) { + final nativeConstraint = nativeConstraints[i]; + final type = _bindings.spine_constraint_data_get_type(nativeConstraint); + switch (type) { + case spine_constraint_type.SPINE_CONSTRAINT_IK: + constraints.add(IkConstraintData._(nativeConstraint.cast())); + break; + case spine_constraint_type.SPINE_CONSTRAINT_TRANSFORM: + constraints.add(TransformConstraintData._(nativeConstraint.cast())); + break; + case spine_constraint_type.SPINE_CONSTRAINT_PATH: + constraints.add(PathConstraintData._(nativeConstraint.cast())); + break; + } + } + return constraints; + } + + /// Adds all bones and constraints and copies of all attachments from the specified skin to this skin. Mesh attachments are not + /// copied, instead a new linked mesh is created. The attachment copies can be modified without affecting the originals. + void copy(Skin other) { + _bindings.spine_skin_copy_skin(_skin, other._skin); + } +} + +/// The base class for all constraint datas. +class ConstraintData { + final T _data; + + ConstraintData._(this._data); + + /// The constraint's name, which is unique across all constraints in the skeleton of the same type. + String getName() { + final Pointer name = _bindings.spine_constraint_data_get_name(_data.cast()).cast(); + return name.toDartString(); + } + + /// The ordinal of this constraint for the order a skeleton's constraints will be applied by + /// [Skeleton.updateWorldTransform]. + int getOrder() { + return _bindings.spine_constraint_data_get_order(_data.cast()); + } + + void setOrder(int order) { + _bindings.spine_constraint_data_set_order(_data.cast(), order); + } + + /// When true, [Skeleton.updateWorldTransform] only updates this constraint if the skin returned by [Skeleton.getSkin] contains + /// this constraint. + /// + /// See [Skin.getConstraints]. + bool isSkinRequired() { + return _bindings.spine_constraint_data_get_is_skin_required(_data.cast()) == 1; + } + + void setIsSkinRequired(bool isSkinRequired) { + _bindings.spine_constraint_data_set_is_skin_required(_data.cast(), isSkinRequired ? -1 : 0); + } +} + +/// Stores the setup pose for an [IkConstraint]. +/// +/// See [IK constraints](http://esotericsoftware.com/spine-ik-constraints) in the Spine User Guide. +class IkConstraintData extends ConstraintData { + IkConstraintData._(spine_ik_constraint_data data) : super._(data); + + /// The bones that are constrained by this IK constraint. + List getBones() { + final List result = []; + final numBones = _bindings.spine_ik_constraint_data_get_num_bones(_data); + final nativeBones = _bindings.spine_ik_constraint_data_get_bones(_data); + for (int i = 0; i < numBones; i++) { + result.add(BoneData._(nativeBones[i])); + } + return result; + } + + /// The bone that is the IK target. + BoneData getTarget() { + return BoneData._(_bindings.spine_ik_constraint_data_get_target(_data)); + } + + void setTarget(BoneData target) { + _bindings.spine_ik_constraint_data_set_target(_data, target._data); + } + + /// For two bone IK, controls the bend direction of the IK bones, either 1 or -1. + int getBendDirection() { + return _bindings.spine_ik_constraint_data_get_bend_direction(_data); + } + + void setBendDirection(int bendDirection) { + _bindings.spine_ik_constraint_data_set_bend_direction(_data, bendDirection); + } + + /// For one bone IK, when true and the target is too close, the bone is scaled to reach it. + bool getCompress() { + return _bindings.spine_ik_constraint_data_get_compress(_data) == -1; + } + + void setCompress(bool compress) { + _bindings.spine_ik_constraint_data_set_compress(_data, compress ? -1 : 0); + } + + /// When true and the target is out of range, the parent bone is scaled to reach it. + /// + /// For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if [getSoftness] is + /// > 0, and 3) if the parent bone has local nonuniform scale, stretch is not applied. + bool getStretch() { + return _bindings.spine_ik_constraint_data_get_stretch(_data) == -1; + } + + void setStretch(bool stretch) { + _bindings.spine_ik_constraint_data_set_stretch(_data, stretch ? -1 : 0); + } + + /// When true and [getCompress] or [getStretch] is used, the bone is scaled on both the X and Y axes. + bool getUniform() { + return _bindings.spine_ik_constraint_data_get_uniform(_data) == -1; + } + + void setUniform(bool uniform) { + _bindings.spine_ik_constraint_data_set_uniform(_data, uniform ? -1 : 0); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + /// + /// For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0. + double getMix() { + return _bindings.spine_ik_constraint_data_get_mix(_data); + } + + void setMix(double mix) { + _bindings.spine_ik_constraint_data_set_mix(_data, mix); + } + + /// For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones + /// will not straighten completely until the target is this far out of range. + double getSoftness() { + return _bindings.spine_ik_constraint_data_get_softness(_data); + } + + void setSoftness(double softness) { + _bindings.spine_ik_constraint_data_set_softness(_data, softness); + } +} + +/// Stores the current pose for an IK constraint. An IK constraint adjusts the rotation of 1 or 2 constrained bones so the tip of +/// the last bone is as close to the target bone as possible. +///

+/// See IK constraints in the Spine User Guide. +class IkConstraint { + final spine_ik_constraint _constraint; + + IkConstraint._(this._constraint); + + /// Applies the constraint to the constrained bones. + void update() { + _bindings.spine_ik_constraint_update(_constraint); + } + + int getOrder() { + return _bindings.spine_ik_constraint_get_order(_constraint); + } + + /// The IK constraint's setup pose data. + IkConstraintData getData() { + return IkConstraintData._(_bindings.spine_ik_constraint_get_data(_constraint)); + } + + /// The bones that will be modified by this IK constraint. + List getBones() { + List result = []; + final num = _bindings.spine_ik_constraint_get_num_bones(_constraint); + final nativeBones = _bindings.spine_ik_constraint_get_bones(_constraint); + for (int i = 0; i < num; i++) { + result.add(Bone._(nativeBones[i])); + } + return result; + } + + /// The bone that is the IK target. + Bone getTarget() { + return Bone._(_bindings.spine_ik_constraint_get_target(_constraint)); + } + + void setTarget(Bone target) { + _bindings.spine_ik_constraint_set_target(_constraint, target._bone); + } + + /// For two bone IK, controls the bend direction of the IK bones, either 1 or -1. + int getBendDirection() { + return _bindings.spine_ik_constraint_get_bend_direction(_constraint); + } + + void setBendDirection(int bendDirection) { + _bindings.spine_ik_constraint_set_bend_direction(_constraint, bendDirection); + } + + /// For one bone IK, when true and the target is too close, the bone is scaled to reach it. + bool getCompress() { + return _bindings.spine_ik_constraint_get_compress(_constraint) == -1; + } + + void setCompress(bool compress) { + _bindings.spine_ik_constraint_set_compress(_constraint, compress ? -1 : 0); + } + + /// When true and the target is out of range, the parent bone is scaled to reach it. + /// + /// For two bone IK: 1) the child bone's local Y translation is set to 0, 2) stretch is not applied if [getSoftness] is + /// > 0, and 3) if the parent bone has local nonuniform scale, stretch is not applied. + bool getStretch() { + return _bindings.spine_ik_constraint_get_stretch(_constraint) == -1; + } + + void setStretch(bool stretch) { + _bindings.spine_ik_constraint_set_stretch(_constraint, stretch ? -1 : 0); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + /// + /// For two bone IK: if the parent bone has local nonuniform scale, the child bone's local Y translation is set to 0. + double getMix() { + return _bindings.spine_ik_constraint_get_mix(_constraint); + } + + void setMix(double mix) { + _bindings.spine_ik_constraint_set_mix(_constraint, mix); + } + + /// For two bone IK, the target bone's distance from the maximum reach of the bones where rotation begins to slow. The bones + /// will not straighten completely until the target is this far out of range. + double getSoftness() { + return _bindings.spine_ik_constraint_get_softness(_constraint); + } + + void setSoftness(double softness) { + _bindings.spine_ik_constraint_set_softness(_constraint, softness); + } + + bool isActive() { + return _bindings.spine_ik_constraint_get_is_active(_constraint) == -1; + } + + void setIsActive(bool isActive) { + _bindings.spine_ik_constraint_set_is_active(_constraint, isActive ? -1 : 0); + } +} + +/// Stores the setup pose for a {@link TransformConstraint}. +/// +/// See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. +class TransformConstraintData extends ConstraintData { + TransformConstraintData._(spine_transform_constraint_data data) : super._(data); + + /// The bones that will be modified by this transform constraint. + List getBones() { + final List result = []; + final numBones = _bindings.spine_transform_constraint_data_get_num_bones(_data); + final nativeBones = _bindings.spine_transform_constraint_data_get_bones(_data); + for (int i = 0; i < numBones; i++) { + result.add(BoneData._(nativeBones[i])); + } + return result; + } + + /// The target bone whose world transform will be copied to the constrained bones. + BoneData getTarget() { + return BoneData._(_bindings.spine_transform_constraint_data_get_target(_data)); + } + + void setTarget(BoneData target) { + _bindings.spine_transform_constraint_data_set_target(_data, target._data); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + double getMixRotate() { + return _bindings.spine_transform_constraint_data_get_mix_rotate(_data); + } + + void setMixRotate(double mixRotate) { + _bindings.spine_transform_constraint_data_set_mix_rotate(_data, mixRotate); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + double getMixX() { + return _bindings.spine_transform_constraint_data_get_mix_x(_data); + } + + void setMixX(double mixX) { + _bindings.spine_transform_constraint_data_set_mix_x(_data, mixX); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + double getMixY() { + return _bindings.spine_transform_constraint_data_get_mix_y(_data); + } + + void setMixY(double mixY) { + _bindings.spine_transform_constraint_data_set_mix_y(_data, mixY); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. + double getMixScaleX() { + return _bindings.spine_transform_constraint_data_get_mix_scale_x(_data); + } + + void setMixScaleX(double mixScaleX) { + _bindings.spine_transform_constraint_data_set_mix_scale_x(_data, mixScaleX); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale Y. + double getMixScaleY() { + return _bindings.spine_transform_constraint_data_get_mix_scale_y(_data); + } + + void setMixScaleY(double mixScaleY) { + _bindings.spine_transform_constraint_data_set_mix_scale_y(_data, mixScaleY); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. + double getMixShearY() { + return _bindings.spine_transform_constraint_data_get_mix_shear_y(_data); + } + + void setMixShearY(double mixShearY) { + _bindings.spine_transform_constraint_data_set_mix_shear_y(_data, mixShearY); + } + + /// An offset added to the constrained bone rotation. + double getOffsetRotation() { + return _bindings.spine_transform_constraint_data_get_offset_rotation(_data); + } + + void setOffsetRotation(double offsetRotation) { + _bindings.spine_transform_constraint_data_set_offset_rotation(_data, offsetRotation); + } + + /// An offset added to the constrained bone X translation. + double getOffsetX() { + return _bindings.spine_transform_constraint_data_get_offset_x(_data); + } + + void setOffsetX(double offsetX) { + _bindings.spine_transform_constraint_data_set_offset_x(_data, offsetX); + } + + /// An offset added to the constrained bone Y translation. + double getOffsetY() { + return _bindings.spine_transform_constraint_data_get_offset_y(_data); + } + + /// An offset added to the constrained bone scaleX. + void setOffsetY(double offsetY) { + _bindings.spine_transform_constraint_data_set_offset_y(_data, offsetY); + } + + /// An offset added to the constrained bone scaleX. + double getOffsetScaleX() { + return _bindings.spine_transform_constraint_data_get_offset_scale_x(_data); + } + + void setOffsetScaleX(double offsetScaleX) { + _bindings.spine_transform_constraint_data_set_offset_x(_data, offsetScaleX); + } + + /// An offset added to the constrained bone scaleY. + double getOffsetScaleY() { + return _bindings.spine_transform_constraint_data_get_offset_scale_y(_data); + } + + void setOffsetScaleY(double offsetScaleY) { + _bindings.spine_transform_constraint_data_set_offset_scale_y(_data, offsetScaleY); + } + + /// An offset added to the constrained bone shearY. + double getOffsetShearY() { + return _bindings.spine_transform_constraint_data_get_offset_shear_y(_data); + } + + void setOffsetShearY(double offsetShearY) { + _bindings.spine_transform_constraint_data_set_offset_shear_y(_data, offsetShearY); + } + + bool isRelative() { + return _bindings.spine_transform_constraint_data_get_is_relative(_data) == -1; + } + + void setIsRelative(bool isRelative) { + _bindings.spine_transform_constraint_data_set_is_relative(_data, isRelative ? -1 : 0); + } + + bool isLocal() { + return _bindings.spine_transform_constraint_data_get_is_local(_data) == -1; + } + + void setIsLocal(bool isLocal) { + _bindings.spine_transform_constraint_data_set_is_local(_data, isLocal ? -1 : 0); + } +} + +/// Stores the current pose for a transform constraint. A transform constraint adjusts the world transform of the constrained +/// bones to match that of the target bone. +/// +/// See [Transform constraints](http://esotericsoftware.com/spine-transform-constraints) in the Spine User Guide. +class TransformConstraint { + final spine_transform_constraint _constraint; + + TransformConstraint._(this._constraint); + + /// Applies the constraint to the constrained bones. + void update() { + _bindings.spine_transform_constraint_update(_constraint); + } + + int getOrder() { + return _bindings.spine_transform_constraint_get_order(_constraint); + } + + /// The transform constraint's setup pose data. + TransformConstraintData getData() { + return TransformConstraintData._(_bindings.spine_transform_constraint_get_data(_constraint)); + } + + /// The bones that will be modified by this transform constraint. + List getBones() { + List result = []; + final num = _bindings.spine_transform_constraint_get_num_bones(_constraint); + final nativeBones = _bindings.spine_transform_constraint_get_bones(_constraint); + for (int i = 0; i < num; i++) { + result.add(Bone._(nativeBones[i])); + } + return result; + } + + /// The target bone whose world transform will be copied to the constrained bones. + Bone getTarget() { + return Bone._(_bindings.spine_transform_constraint_get_target(_constraint)); + } + + void setTarget(Bone target) { + _bindings.spine_transform_constraint_set_target(_constraint, target._bone); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + double getMixRotate() { + return _bindings.spine_transform_constraint_get_mix_rotate(_constraint); + } + + void setMixRotate(double mixRotate) { + _bindings.spine_transform_constraint_set_mix_rotate(_constraint, mixRotate); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + double getMixX() { + return _bindings.spine_transform_constraint_get_mix_x(_constraint); + } + + void setMixX(double mixX) { + _bindings.spine_transform_constraint_set_mix_x(_constraint, mixX); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + double getMixY() { + return _bindings.spine_transform_constraint_get_mix_y(_constraint); + } + + void setMixY(double mixY) { + _bindings.spine_transform_constraint_set_mix_y(_constraint, mixY); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. + double getMixScaleX() { + return _bindings.spine_transform_constraint_get_mix_scale_x(_constraint); + } + + void setMixScaleX(double mixScaleX) { + _bindings.spine_transform_constraint_set_mix_scale_x(_constraint, mixScaleX); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained scale X. + double getMixScaleY() { + return _bindings.spine_transform_constraint_get_mix_scale_y(_constraint); + } + + void setMixScaleY(double mixScaleY) { + _bindings.spine_transform_constraint_set_mix_scale_y(_constraint, mixScaleY); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained shear Y. + double getMixShearY() { + return _bindings.spine_transform_constraint_get_mix_shear_y(_constraint); + } + + void setMixShearY(double mixShearY) { + _bindings.spine_transform_constraint_set_mix_shear_y(_constraint, mixShearY); + } + + bool isActive() { + return _bindings.spine_transform_constraint_get_is_active(_constraint) == -1; + } + + void setIsActive(bool isActive) { + _bindings.spine_transform_constraint_set_is_active(_constraint, isActive ? -1 : 0); + } +} + +/// Stores the setup pose for a [PathConstraint]. +/// +/// See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. +class PathConstraintData extends ConstraintData { + PathConstraintData._(spine_path_constraint_data data) : super._(data); + + /// The bones that will be modified by this path constraint. + List getBones() { + final List result = []; + final numBones = _bindings.spine_path_constraint_data_get_num_bones(_data); + final nativeBones = _bindings.spine_path_constraint_data_get_bones(_data); + for (int i = 0; i < numBones; i++) { + result.add(BoneData._(nativeBones[i])); + } + return result; + } + + /// The slot whose path attachment will be used to constrained the bones. + SlotData getTarget() { + return SlotData._(_bindings.spine_path_constraint_data_get_target(_data)); + } + + void setTarget(SlotData target) { + _bindings.spine_path_constraint_data_set_target(_data, target._data); + } + + /// The mode for positioning the first bone on the path. + PositionMode getPositionMode() { + return PositionMode.values[_bindings.spine_path_constraint_data_get_position_mode(_data)]; + } + + void setPositionMode(PositionMode positionMode) { + _bindings.spine_path_constraint_data_set_position_mode(_data, positionMode.value); + } + + /// The mode for positioning the bones after the first bone on the path. + SpacingMode getSpacingMode() { + return SpacingMode.values[_bindings.spine_path_constraint_data_get_spacing_mode(_data)]; + } + + void setSpacingMode(SpacingMode spacingMode) { + _bindings.spine_path_constraint_data_set_spacing_mode(_data, spacingMode.value); + } + + /// The mode for adjusting the rotation of the bones. + RotateMode getRotateMode() { + return RotateMode.values[_bindings.spine_path_constraint_data_get_rotate_mode(_data)]; + } + + void setRotateMode(RotateMode rotateMode) { + _bindings.spine_path_constraint_data_set_rotate_mode(_data, rotateMode.value); + } + + /// An offset added to the constrained bone rotation. + double getOffsetRotation() { + return _bindings.spine_path_constraint_data_get_offset_rotation(_data); + } + + void setOffsetRotation(double offsetRotation) { + _bindings.spine_path_constraint_data_set_offset_rotation(_data, offsetRotation); + } + + /// The position along the path. + double getPosition() { + return _bindings.spine_path_constraint_data_get_position(_data); + } + + void setPosition(double position) { + _bindings.spine_path_constraint_data_set_position(_data, position); + } + + /// The spacing between bones. + double getSpacing() { + return _bindings.spine_path_constraint_data_get_spacing(_data); + } + + void setSpacing(double spacing) { + _bindings.spine_path_constraint_data_set_spacing(_data, spacing); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + double getMixRotate() { + return _bindings.spine_path_constraint_data_get_mix_rotate(_data); + } + + void setMixRotate(double mixRotate) { + _bindings.spine_path_constraint_data_set_mix_rotate(_data, mixRotate); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + double getMixX() { + return _bindings.spine_path_constraint_data_get_mix_x(_data); + } + + void setMixX(double mixX) { + _bindings.spine_path_constraint_data_set_mix_x(_data, mixX); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + double getMixY() { + return _bindings.spine_path_constraint_data_get_mix_x(_data); + } + + void setMixY(double mixY) { + _bindings.spine_path_constraint_data_set_mix_y(_data, mixY); + } +} + +/// Stores the current pose for a path constraint. A path constraint adjusts the rotation, translation, and scale of the +/// constrained bones so they follow a [PathAttachment]. +/// +/// See [Path constraints](http://esotericsoftware.com/spine-path-constraints) in the Spine User Guide. +class PathConstraint { + final spine_path_constraint _constraint; + + PathConstraint._(this._constraint); + + /// Applies the constraint to the constrained bones. + void update() { + _bindings.spine_path_constraint_update(_constraint); + } + + int getOrder() { + return _bindings.spine_path_constraint_get_order(_constraint); + } + + /// The bones that will be modified by this path constraint. + List getBones() { + List result = []; + final num = _bindings.spine_path_constraint_get_num_bones(_constraint); + final nativeBones = _bindings.spine_path_constraint_get_bones(_constraint); + for (int i = 0; i < num; i++) { + result.add(Bone._(nativeBones[i])); + } + return result; + } + + /// The slot whose path attachment will be used to constrained the bones. + Slot getTarget() { + return Slot._(_bindings.spine_path_constraint_get_target(_constraint)); + } + + void setTarget(Slot target) { + _bindings.spine_path_constraint_set_target(_constraint, target._slot); + } + + /// The position along the path. + double getPosition() { + return _bindings.spine_path_constraint_get_position(_constraint); + } + + void setPosition(double position) { + _bindings.spine_path_constraint_set_position(_constraint, position); + } + + /// The spacing between bones. + double getSpacing() { + return _bindings.spine_path_constraint_get_spacing(_constraint); + } + + void setSpacing(double spacing) { + _bindings.spine_path_constraint_set_spacing(_constraint, spacing); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained rotation. + double getMixRotate() { + return _bindings.spine_path_constraint_get_mix_rotate(_constraint); + } + + void setMixRotate(double mixRotate) { + _bindings.spine_path_constraint_set_mix_rotate(_constraint, mixRotate); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation X. + double getMixX() { + return _bindings.spine_path_constraint_get_mix_x(_constraint); + } + + void setMixX(double mixX) { + _bindings.spine_path_constraint_set_mix_x(_constraint, mixX); + } + + /// A percentage (0-1) that controls the mix between the constrained and unconstrained translation Y. + double getMixY() { + return _bindings.spine_path_constraint_get_mix_y(_constraint); + } + + void setMixY(double mixY) { + _bindings.spine_path_constraint_set_mix_y(_constraint, mixY); + } + + bool isActive() { + return _bindings.spine_path_constraint_get_is_active(_constraint) == -1; + } + + void setIsActive(bool isActive) { + _bindings.spine_path_constraint_set_is_active(_constraint, isActive ? -1 : 0); + } +} + +/// Stores the current pose for a skeleton. +/// +/// See [Instance objects](http://esotericsoftware.com/spine-runtime-architecture#Instance-objects) in the Spine +/// Runtimes Guide. +class Skeleton { + final spine_skeleton _skeleton; + + Skeleton._(this._skeleton); + + /// Caches information about bones and constraints. Must be called if the [getSkin] is modified or 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 all constraints. + /// + /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + /// Runtimes Guide. + void updateWorldTransform() { + _bindings.spine_skeleton_update_world_transform(_skeleton); + } + + /// Temporarily sets the root bone as a child of the specified bone, then updates the world transform for each bone and applies + /// all constraints. + /// + /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine + /// Runtimes Guide. + void updateWorldTransformBone(Bone parent) { + _bindings.spine_skeleton_update_world_transform_bone(_skeleton, parent._bone); + } + + /// Sets the bones, constraints, slots, and draw order 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); + } + + /// Sets the slots and draw order to their setup pose values. + void setSlotsToSetupPose() { + _bindings.spine_skeleton_set_slots_to_setup_pose(_skeleton); + } + + /// Finds a bone by comparing each bone's name. It is more efficient to cache the results of this method than to call it + /// repeatedly. + Bone? findBone(String boneName) { + final nameNative = boneName.toNativeUtf8(allocator: _allocator); + final bone = _bindings.spine_skeleton_find_bone(_skeleton, nameNative.cast()); + _allocator.free(nameNative); + if (bone.address == nullptr.address) return null; + return Bone._(bone); + } + + /// Finds a slot by comparing each slot's name. It is more efficient to cache the results of this method than to call it + /// repeatedly. + Slot? findSlot(String slotName) { + final nameNative = slotName.toNativeUtf8(allocator: _allocator); + final slot = _bindings.spine_skeleton_find_slot(_skeleton, nameNative.cast()); + _allocator.free(nameNative); + if (slot.address == nullptr.address) return null; + return Slot._(slot); + } + + /// Sets a skin by name. + /// + /// See [setSkin]. + void setSkinByName(String skinName) { + final nameNative = skinName.toNativeUtf8(allocator: _allocator); + _bindings.spine_skeleton_set_skin_by_name(_skeleton, nameNative.cast()); + _allocator.free(nameNative); + } + + /// Sets the skin used to look up attachments before looking in the default skin (see [SkeletonData.getDefaultSkin]). If the + /// skin is changed, [updateCache] is called. + /// + /// 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 + /// [setSlotsToSetupPose]. Also, often [AnimationState.apply] 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. + void setSkin(Skin skin) { + _bindings.spine_skeleton_set_skin(_skeleton, skin._skin); + } + + /// Finds an attachment by looking in the currently set skin (see [getSkin]) and default skin (see [SkeletonData.getDefaultSkin]) using + /// the slot name and attachment name. + /// + /// See [getAttachment]. + Attachment? getAttachmentByName(String slotName, String attachmentName) { + final slotNameNative = slotName.toNativeUtf8(allocator: _allocator); + final attachmentNameNative = attachmentName.toNativeUtf8(allocator: _allocator); + final attachment = _bindings.spine_skeleton_get_attachment_by_name(_skeleton, slotNameNative.cast(), attachmentNameNative.cast()); + _allocator.free(slotNameNative); + _allocator.free(attachmentNameNative); + if (attachment.address == nullptr.address) return null; + return Attachment._toSubclass(attachment); + } + + /// Finds an attachment by looking in the currently set skin (see [getSkin]) and default skin (see [SkeletonData.getDefaultSkin]) using the + /// slot index and attachment name. First the skin is checked and if the attachment was not found, the default skin is checked. + /// + /// See [Runtime skins](http://esotericsoftware.com/spine-runtime-skins) in the Spine Runtimes Guide. + Attachment? getAttachment(int slotIndex, String attachmentName) { + final attachmentNameNative = attachmentName.toNativeUtf8(allocator: _allocator); + final attachment = _bindings.spine_skeleton_get_attachment(_skeleton, slotIndex, attachmentNameNative.cast()); + _allocator.free(attachmentNameNative); + if (attachment.address == nullptr.address) return null; + return Attachment._toSubclass(attachment); + } + + /// A convenience method to set an attachment by finding the slot with [findSlot], finding the attachment with + /// [getAttachment], then setting the slot's attachment. The [attachmentName] may be an empty string to clear the slot's attachment. + void setAttachment(String slotName, String attachmentName) { + final slotNameNative = slotName.toNativeUtf8(allocator: _allocator); + final attachmentNameNative = attachmentName.toNativeUtf8(allocator: _allocator); + _bindings.spine_skeleton_set_attachment(_skeleton, slotNameNative.cast(), attachmentNameNative.cast()); + _allocator.free(slotNameNative); + _allocator.free(attachmentNameNative); + } + + /// Finds an IK constraint by comparing each IK constraint's name. It is more efficient to cache the results of this method + /// than to call it repeatedly. + IkConstraint? findIkConstraint(String constraintName) { + final nameNative = constraintName.toNativeUtf8(allocator: _allocator); + final constraint = _bindings.spine_skeleton_find_ik_constraint(_skeleton, nameNative.cast()); + _allocator.free(nameNative); + if (constraint.address == nullptr.address) return null; + return IkConstraint._(constraint); + } + + /// Finds a transform constraint by comparing each transform constraint's name. It is more efficient to cache the results of + /// this method than to call it repeatedly. + TransformConstraint? findTransformConstraint(String constraintName) { + final nameNative = constraintName.toNativeUtf8(allocator: _allocator); + final constraint = _bindings.spine_skeleton_find_transform_constraint(_skeleton, nameNative.cast()); + _allocator.free(nameNative); + if (constraint.address == nullptr.address) return null; + return TransformConstraint._(constraint); + } + + /// Finds a path constraint by comparing each path constraint's name. It is more efficient to cache the results of this method + /// than to call it repeatedly. + PathConstraint? findPathConstraint(String constraintName) { + final nameNative = constraintName.toNativeUtf8(allocator: _allocator); + final constraint = _bindings.spine_skeleton_find_path_constraint(_skeleton, nameNative.cast()); + _allocator.free(nameNative); + if (constraint.address == nullptr.address) return null; + return PathConstraint._(constraint); + } + + /// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose. + Bounds getBounds() { + final nativeBounds = _bindings.spine_skeleton_get_bounds(_skeleton); + final bounds = Bounds(_bindings.spine_bounds_get_x(nativeBounds), _bindings.spine_bounds_get_y(nativeBounds), + _bindings.spine_bounds_get_width(nativeBounds), _bindings.spine_bounds_get_height(nativeBounds)); + _allocator.free(nativeBounds); + return bounds; + } + + /// Returns the root bone, or null if the skeleton has no bones. + Bone? getRootBone() { + final bone = _bindings.spine_skeleton_get_root_bone(_skeleton); + if (bone.address == nullptr.address) return null; + return Bone._(bone); + } + + /// The skeleton's setup pose data. + SkeletonData? getData() { + final data = _bindings.spine_skeleton_get_data(_skeleton); + if (data.address == nullptr.address) return null; + return SkeletonData._(data); + } + + /// The skeleton's bones, sorted parent first. The root bone is always the first bone. + List getBones() { + final List bones = []; + final numBones = _bindings.spine_skeleton_get_num_bones(_skeleton); + final nativeBones = _bindings.spine_skeleton_get_bones(_skeleton); + for (int i = 0; i < numBones; i++) { + bones.add(Bone._(nativeBones[i])); + } + return bones; + } + + /// The skeleton's slots. + List getSlots() { + final List slots = []; + final numSlots = _bindings.spine_skeleton_get_num_slots(_skeleton); + final nativeSlots = _bindings.spine_skeleton_get_slots(_skeleton); + for (int i = 0; i < numSlots; i++) { + slots.add(Slot._(nativeSlots[i])); + } + return slots; + } + + /// The skeleton's slots in the order they should be drawn. The returned array may be modified to change the draw order. + List getDrawOrder() { + final List slots = []; + final numSlots = _bindings.spine_skeleton_get_num_draw_order(_skeleton); + final nativeDrawOrder = _bindings.spine_skeleton_get_draw_order(_skeleton); + for (int i = 0; i < numSlots; i++) { + slots.add(Slot._(nativeDrawOrder[i])); + } + return slots; + } + + /// The skeleton's IK constraints. + List getIkConstraints() { + final List constraints = []; + final numConstraints = _bindings.spine_skeleton_get_num_ik_constraints(_skeleton); + final nativeConstraints = _bindings.spine_skeleton_get_ik_constraints(_skeleton); + for (int i = 0; i < numConstraints; i++) { + constraints.add(IkConstraint._(nativeConstraints[i])); + } + return constraints; + } + + /// The skeleton's path constraints. + List getPathConstraints() { + final List constraints = []; + final numConstraints = _bindings.spine_skeleton_get_num_path_constraints(_skeleton); + final nativeConstraints = _bindings.spine_skeleton_get_path_constraints(_skeleton); + for (int i = 0; i < numConstraints; i++) { + constraints.add(PathConstraint._(nativeConstraints[i])); + } + return constraints; + } + + /// The skeleton's transform constraints. + List getTransformConstraints() { + final List constraints = []; + final numConstraints = _bindings.spine_skeleton_get_num_transform_constraints(_skeleton); + final nativeConstraints = _bindings.spine_skeleton_get_transform_constraints(_skeleton); + for (int i = 0; i < numConstraints; i++) { + constraints.add(TransformConstraint._(nativeConstraints[i])); + } + return constraints; + } + + /// The skeleton's current skin. + Skin? getSkin() { + final skin = _bindings.spine_skeleton_get_skin(_skeleton); + if (skin.address == nullptr.address) return null; + return Skin._(skin); + } + + /// The color to tint all the skeleton's attachments. + Color getColor() { + final color = _bindings.spine_skeleton_get_color(_skeleton); + return Color(_bindings.spine_color_get_r(color), _bindings.spine_color_get_g(color), _bindings.spine_color_get_b(color), + _bindings.spine_color_get_a(color)); + } + + void setColor(Color color) { + _bindings.spine_skeleton_set_color(_skeleton, color.r, color.g, color.b, color.a); + } + + /// Sets the skeleton X and Y position, which is added to the root bone worldX and worldY position. + /// + /// Bones that do not inherit translation are still affected by this property. + void setPosition(double x, double y) { + _bindings.spine_skeleton_set_position(_skeleton, x, y); + } + + /// Sets the skeleton X position, which is added to the root bone worldX position. + /// + /// Bones that do not inherit translation are still affected by this property. + double getX() { + return _bindings.spine_skeleton_get_x(_skeleton); + } + + void setX(double x) { + _bindings.spine_skeleton_set_x(_skeleton, x); + } + + /// Sets the skeleton Y position, which is added to the root bone worldY position. + ///

+ /// Bones that do not inherit translation are still affected by this property. + double getY() { + return _bindings.spine_skeleton_get_x(_skeleton); + } + + void setY(double y) { + _bindings.spine_skeleton_set_y(_skeleton, y); + } + + /// Scales the entire skeleton on the X axis. + /// + /// Bones that do not inherit scale are still affected by this property. + double getScaleX() { + return _bindings.spine_skeleton_get_scale_x(_skeleton); + } + + void setScaleX(double scaleX) { + _bindings.spine_skeleton_set_scale_x(_skeleton, scaleX); + } + + /// Scales the entire skeleton on the Y axis. + /// + /// Bones that do not inherit scale are still affected by this property. + double getScaleY() { + return _bindings.spine_skeleton_get_scale_x(_skeleton); + } + + void setScaleY(double scaleY) { + _bindings.spine_skeleton_set_scale_y(_skeleton, scaleY); + } +} + +/// Stores a list of timelines to animate a skeleton's pose over time. +class Animation { + final spine_animation _animation; + + Animation._(this._animation); + + /// The animation's name, which is unique across all animations in the skeleton. + String getName() { + final Pointer value = _bindings.spine_animation_get_name(_animation).cast(); + return value.toDartString(); + } + + /// The duration of the animation in seconds, which is usually the highest time of all frames in the timeline. The duration is + /// used to know when it has completed and when it should loop back to the start. + double getDuration() { + return _bindings.spine_animation_get_duration(_animation); + } +} + +/// Controls how timeline values are mixed with setup pose values or current pose values when a timeline is applied with +/// alpha < 1. +enum MixBlend { + /// Transitions from the setup value to the timeline value (the current value is not used). Before the first frame, the + /// setup value is set. + setup(0), + + /// Transitions from the current value to the timeline value. Before the first frame, transitions from the current value to + /// the setup value. Timelines which perform instant transitions, such as {@link DrawOrderTimeline} or + /// {@link AttachmentTimeline}, use the setup value before the first frame. + ///

+ /// first is intended for the first animations applied, not for animations layered on top of those. + first(1), + + /// Transitions from the current value to the timeline value. No change is made before the first frame (the current value is + /// kept until the first frame). + ///

+ /// replace is intended for animations layered on top of others, not for the first animations applied. + replace(2), + + /// Transitions from the current value to the current value plus the timeline value. No change is made before the first + /// frame (the current value is kept until the first frame). + ///

+ /// add is intended for animations layered on top of others, not for the first animations applied. Properties + /// set by additive animations must be set manually or by another animation before applying the additive animations, else the + /// property values will increase each time the additive animations are applied. + add(3); + + final int value; + + const MixBlend(this.value); +} + +/// Stores settings and other state for the playback of an animation on an [AnimationState] track. +/// +/// References to a track entry must not be kept after the dispose [EventType] is reported to [AnimationStateListener]. +class TrackEntry { + final spine_track_entry _entry; + final AnimationState _state; + + TrackEntry._(this._entry, this._state); + + /// The index of the track where this track entry is either current or queued. + /// + /// See [AnimationState.getCurrent]. + int getTtrackIndex() { + return _bindings.spine_track_entry_get_track_index(_entry); + } + + /// The animation to apply for this track entry. + Animation getAnimation() { + return Animation._(_bindings.spine_track_entry_get_animation(_entry)); + } + + /// If true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + /// duration. + bool getLoop() { + return _bindings.spine_track_entry_get_loop(_entry) == -1; + } + + void setLoop(bool loop) { + _bindings.spine_track_entry_set_loop(_entry, loop ? -1 : 0); + } + + /// Seconds to postpone playing the animation. When this track entry is the current track entry, delay + /// postpones incrementing the [getTrackTime]. When this track entry is queued, delay is the time from + /// the start of the previous animation to when this track entry will become the current track entry (ie when the previous + /// track entry [getTrackTime] >= this track entry's delay). + /// + /// [getTimeScale] affects the delay. + /// + /// When using [AnimationState.addAnimation] with a delay <= 0, the delay + /// is set using the mix duration from the [AnimationStateData]. If [getMixDuration] is set afterward, the delay + /// may need to be adjusted. + bool getHoldPrevious() { + return _bindings.spine_track_entry_get_hold_previous(_entry) == -1; + } + + void setHoldPrevious(bool holdPrevious) { + _bindings.spine_track_entry_set_hold_previous(_entry, holdPrevious ? -1 : 0); + } + + /// If true, the animation will be applied in reverse. Events are not fired when an animation is applied in reverse. + bool getReverse() { + return _bindings.spine_track_entry_get_reverse(_entry) == -1; + } + + void setReverse(bool reverse) { + _bindings.spine_track_entry_set_reverse(_entry, reverse ? -1 : 0); + } + + /// If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the + /// shortest rotation direction may change during the mix. + /// + /// If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest + /// of the mix. Defaults to false. + bool getShortestRotation() { + return _bindings.spine_track_entry_get_shortest_rotation(_entry) == 1; + } + + void setShortestRotation(bool shortestRotation) { + _bindings.spine_track_entry_set_shortest_rotation(_entry, shortestRotation ? -1 : 0); + } + + /// Seconds to postpone playing the animation. When this track entry is the current track entry, delay + /// postpones incrementing the [getTrackTime]. When this track entry is queued, delay is the time from + /// the start of the previous animation to when this track entry will become the current track entry (ie when the previous + /// track entry [getTrackTime] >= this track entry's delay). + /// + /// [getTimeScale] affects the delay. + /// + /// When using [AnimationState.addAnimation] with a delay <= 0, the delay + /// is set using the mix duration from the [AnimationStateData]. If [getMixDuration] is set afterward, the delay + /// may need to be adjusted. + double getDelay() { + return _bindings.spine_track_entry_get_delay(_entry); + } + + void setDelay(double delay) { + _bindings.spine_track_entry_set_delay(_entry, delay); + } + + /// Current time in seconds this track entry has been the current track entry. The track time determines + /// [getAnimationTime]. The track time can be set to start the animation at a time other than 0, without affecting + /// looping. + double getTrackTime() { + return _bindings.spine_track_entry_get_track_time(_entry); + } + + void setTrackTime(double trackTime) { + _bindings.spine_track_entry_set_track_time(_entry, trackTime); + } + + /// The track time in seconds when this animation will be removed from the track. Defaults to the highest possible float + /// value, meaning the animation will be applied until a new animation is set or the track is cleared. If the track end time + /// is reached, no other animations are queued for playback, and mixing from any previous animations is complete, then the + /// properties keyed by the animation are set to the setup pose and the track is cleared. + /// + /// It may be desired to use [AnimationState.addEmptyAnimation] rather than have the animation + /// abruptly cease being applied. + double getTrackEnd() { + return _bindings.spine_track_entry_get_track_end(_entry); + } + + void setTrackEnd(double trackEnd) { + _bindings.spine_track_entry_set_track_end(_entry, trackEnd); + } + + /// Seconds when this animation starts, both initially and after looping. Defaults to 0. + /// + /// When changing the animationStart time, it often makes sense to set [getAnimationLast] to the same + /// value to prevent timeline keys before the start time from triggering. + double getAnimationStart() { + return _bindings.spine_track_entry_get_animation_start(_entry); + } + + void setAnimationStart(double animationStart) { + _bindings.spine_track_entry_set_animation_start(_entry, animationStart); + } + + /// Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will + /// loop back to [getAnimationStart] at this time. Defaults to the animation [Animation.getDuration]. + double getAnimationEnd() { + return _bindings.spine_track_entry_get_animation_end(_entry); + } + + void setAnimationEnd(double animationEnd) { + _bindings.spine_track_entry_set_animation_end(_entry, animationEnd); + } + + /// The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this + /// animation is applied, event timelines will fire all events between the animationLast time (exclusive) and + /// animationTime (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation + /// is applied. + double getAnimationLast() { + return _bindings.spine_track_entry_get_animation_last(_entry); + } + + void setAnimationLast(double animationLast) { + _bindings.spine_track_entry_set_animation_last(_entry, animationLast); + } + + /// Uses [getTrackTime] to compute the animationTime. When the trackTime is 0, the + /// animationTime is equal to the animationStart time. + ///

+ /// The animationTime is between [getAnimationStart] and [getAnimationEnd], except if this + /// track entry is non-looping and [getAnimationEnd] is >= to the animation [Animation.getDuration], then + /// animationTime continues to increase past [getAnimationEnd]. + double getAnimationTime() { + return _bindings.spine_track_entry_get_animation_time(_entry); + } + + /// Multiplier for the delta time when this track entry is updated, causing time for this animation to pass slower or + /// faster. Defaults to 1. + /// + /// Values < 0 are not supported. To play an animation in reverse, use [getReverse]. + /// + /// [getMixTime] is not affected by track entry time scale, so [getMixDuration] may need to be adjusted to + /// match the animation speed. + /// + /// When using [AnimationState.addAnimation] with a delay <= 0, the + /// [getDelay] is set using the mix duration from the [AnimationStateData], assuming time scale to be 1. If + /// the time scale is not 1, the delay may need to be adjusted. + /// + /// See [AnimationState.getTimeScale] for affecting all animations. + double getTimeScale() { + return _bindings.spine_track_entry_get_time_scale(_entry); + } + + void setTimeScale(double timeScale) { + _bindings.spine_track_entry_set_time_scale(_entry, timeScale); + } + + /// Values < 1 mix this animation with the skeleton's current pose (usually the pose resulting from lower tracks). Defaults + /// to 1, which overwrites the skeleton's current pose with this animation. + /// + /// Typically track 0 is used to completely pose the skeleton, then alpha is used on higher tracks. It doesn't make sense to + /// use alpha on track 0 if the skeleton pose is from the last frame render. + Future getAlpha() async { + return _bindings.spine_track_entry_get_alpha(_entry); + } + + void setAlpha(double alpha) { + _bindings.spine_track_entry_set_alpha(_entry, alpha); + } + + /// When the mix percentage ([getMixTime] / [getMixDuration]) is less than the + /// eventThreshold, event timelines are applied while this animation is being mixed out. Defaults to 0, so event + /// timelines are not applied while this animation is being mixed out. + double getEventThreshold() { + return _bindings.spine_track_entry_get_event_threshold(_entry); + } + + void setEventThreshold(double eventThreshold) { + _bindings.spine_track_entry_set_event_threshold(_entry, eventThreshold); + } + + /// When the mix percentage ([getMixTime] / [getMixDuration]) is less than the + /// attachmentThreshold, attachment timelines are applied while this animation is being mixed out. Defaults to + /// 0, so attachment timelines are not applied while this animation is being mixed out. + double getAttachmentThreshold() { + return _bindings.spine_track_entry_get_attachment_threshold(_entry); + } + + void setAttachmentThreshold(double attachmentThreshold) { + _bindings.spine_track_entry_set_attachment_threshold(_entry, attachmentThreshold); + } + + /// When the mix percentage ([getMixTime] / [getMixDuration]) is less than the + /// drawOrderThreshold, draw order timelines are applied while this animation is being mixed out. Defaults to 0, + /// so draw order timelines are not applied while this animation is being mixed out. + double getDrawOrderThreshold() { + return _bindings.spine_track_entry_get_draw_order_threshold(_entry); + } + + void setDrawOrderThreshold(double drawOrderThreshold) { + _bindings.spine_track_entry_set_draw_order_threshold(_entry, drawOrderThreshold); + } + + /// The animation queued to start after this animation, or null if there is none. next makes up a doubly linked + /// list. + /// + /// See [AnimationState.clearNext] to truncate the list. + TrackEntry? getNext() { + final next = _bindings.spine_track_entry_get_next(_entry); + if (next.address == nullptr.address) return null; + return TrackEntry._(next, _state); + } + + /// Returns true if at least one loop has been completed. + bool isComplete() { + return _bindings.spine_track_entry_is_complete(_entry) == -1; + } + + /// Seconds from 0 to the [getMixDuration] when mixing from the previous animation to this animation. May be + /// slightly more than mixDuration when the mix is complete. + double getMixTime() { + return _bindings.spine_track_entry_get_mix_time(_entry); + } + + void setMixTime(double mixTime) { + _bindings.spine_track_entry_set_mix_time(_entry, mixTime); + } + + /// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by + /// [AnimationStateData.getMix] based on the animation before this animation (if any). + /// + /// A mix duration of 0 still mixes out over one frame to provide the track entry being mixed out a chance to revert the + /// properties it was animating. A mix duration of 0 can be set at any time to end the mix on the next + /// [AnimationState.update]. + /// + /// The mixDuration can be set manually rather than use the value from + /// [AnimationStateData.getMix]. In that case, the mixDuration can be set for a new + /// track entry only before [AnimationState.update] is first called. + ///

+ /// When using [AnimationState.addAnimation] with a delay <= 0, the + /// [getDelay] is set using the mix duration from the [AnimationStateData]. If mixDuration is set + /// afterward, the delay may need to be adjusted. For example: + /// entry.delay = entry.previous.getTrackComplete() - entry.mixDuration; + double getMixDuration() { + return _bindings.spine_track_entry_get_mix_duration(_entry); + } + + void setMixDuration(double mixDuration) { + _bindings.spine_track_entry_set_mix_duration(_entry, mixDuration); + } + + /// Controls how properties keyed in the animation are mixed with lower tracks. Defaults to [MixBlend.replace]. + /// + /// Track entries on track 0 ignore this setting and always use {@link MixBlend#first}. + /// + /// The mixBlend can be set for a new track entry only before [AnimationState.apply] is first + /// called. + MixBlend getMixBlend() { + return MixBlend.values[_bindings.spine_track_entry_get_mix_blend(_entry)]; + } + + void setMixBlend(MixBlend mixBlend) { + _bindings.spine_track_entry_set_mix_blend(_entry, mixBlend.value); + } + + /// The track entry for the previous animation when mixing from the previous animation to this animation, or null if no + /// mixing is currently occurring. When mixing from multiple animations, mixingFrom makes up a linked list. + TrackEntry? getMixingFrom() { + final from = _bindings.spine_track_entry_get_mixing_from(_entry); + if (from.address == nullptr.address) return null; + return TrackEntry._(from, _state); + } + + /// The track entry for the next animation when mixing from this animation to the next animation, or null if no mixing is + /// currently occurring. When mixing to multiple animations, mixingTo makes up a linked list. + TrackEntry? getMixingTo() { + final to = _bindings.spine_track_entry_get_mixing_to(_entry); + if (to.address == nullptr.address) return null; + return TrackEntry._(to, _state); + } + + /// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the + /// long way around when using alpha and starting animations on other tracks. + /// + /// Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way around. + /// The two rotations likely change over time, so which direction is the short or long way also changes. + /// If the short way was always chosen, bones would flip to the other side when that direction became the long way. + /// TrackEntry chooses the short way the first time it is applied and remembers that direction. + void resetRotationDirections() { + _bindings.spine_track_entry_reset_rotation_directions(_entry); + } + + /// If this track entry is non-looping, the track time in seconds when [getAnimationEnd] is reached, or the current + /// [getTrackTime] if it has already been reached. If this track entry is looping, the track time when this + /// animation will reach its next [getAnimationEnd] (the next loop completion). + double getTrackComplete() { + return _bindings.spine_track_entry_get_track_complete(_entry); + } + + /// The listener for events generated by this track entry, or null. + /// + /// A track entry returned from [AnimationState.setAnimation] is already the current animation + /// for the track, so the track entry listener will not be called for [EventType.start]. + void setListener(AnimationStateListener? listener) { + _state._setTrackEntryListener(_entry, listener); + } +} + +/// The event type passed to [AnimationStateListener] +enum EventType { + /// Emitted when [TrackEntry] has been set as the current entry. [EventType.end] will occur when this entry will no + /// longer be applied. + start, + + /// Emitted when another entry has replaced the current entry. This entry may continue being applied for + /// mixing. + interrupt, + + /// Emitted when this entry will never be applied again. This only occurs if this entry has previously been set as the + /// current entry ([EventType.start] was emitted). + end, + + /// Emitted every time the current entry's animation completes a loop. This may occur during mixing (after + /// [EventType.interrupted] is emitted). + /// + /// If [TrackEntry.getMixingTo] of the entry reported by the event is not null, the entry is mixing out (it is not the current entry). + /// + /// Because this event is triggered at the end of [AnimationState.apply], any animations set in response to + /// the event won't be applied until the next time the [AnimationState] is applied. + complete, + + /// Emitted when this entry will be disposed. This may occur without the entry ever being set as the current entry. + /// + /// References to the entry should not be kept after dispose is called, as it may be destroyed or reused. + dispose, + + /// Invoked when the current entry's animation triggers an event. This may occur during mixing (after + /// [EventType.interrupt] is emitted), see [TrackEntry.getEventThreshold]. + /// + /// Because this event is triggered at the end of [AnimationState.apply], any animations set in response to + /// the event won't be applied until the next time the [AnimationState] is applied. + event +} + +/// Stores the setup pose values for an [Event]. +/// +/// See Events in the Spine User Guide. +class EventData { + final spine_event_data _data; + + EventData._(this._data); + + /// The name of the event, which is unique across all events in the skeleton. + String getName() { + final Pointer value = _bindings.spine_event_data_get_name(_data).cast(); + return value.toDartString(); + } + + int getIntValue() { + return _bindings.spine_event_data_get_int_value(_data); + } + + void setIntValue(int value) { + _bindings.spine_event_data_set_int_value(_data, value); + } + + double getFloatValue() { + return _bindings.spine_event_data_get_float_value(_data); + } + + void setFloatValue(double value) { + _bindings.spine_event_data_set_float_value(_data, value); + } + + String getStringValue() { + final Pointer value = _bindings.spine_event_data_get_string_value(_data).cast(); + return value.toDartString(); + } + + void setStringValue(String value) { + final nativeString = value.toNativeUtf8(allocator: _allocator); + _bindings.spine_event_data_set_string_value(_data, nativeString.cast()); + _allocator.free(nativeString); + } + + String getAudioPath() { + final Pointer value = _bindings.spine_event_data_get_audio_path(_data).cast(); + return value.toDartString(); + } + + double getVolume() { + return _bindings.spine_event_data_get_volume(_data); + } + + void setVolume(double volume) { + _bindings.spine_event_data_set_volume(_data, volume); + } + + double getBalance() { + return _bindings.spine_event_data_get_balance(_data); + } + + void setBalance(double value) { + _bindings.spine_event_data_set_balance(_data, value); + } +} + +/// Stores the current pose values for an {@link Event}. +/// +/// See [AnimationStateListener], [EventType.event], and +/// Events in the Spine User Guide. +class Event { + final spine_event _event; + + Event._(this._event); + + /// The events's setup pose data. + EventData getData() { + return EventData._(_bindings.spine_event_get_data(_event)); + } + + /// The animation time this event was keyed. + double getTime() { + return _bindings.spine_event_get_time(_event); + } + + int getIntValue() { + return _bindings.spine_event_get_int_value(_event); + } + + void setIntValue(int value) { + _bindings.spine_event_set_int_value(_event, value); + } + + double getFloatValue() { + return _bindings.spine_event_get_float_value(_event); + } + + void setFloatValue(double value) { + _bindings.spine_event_set_float_value(_event, value); + } + + String getStringValue() { + final Pointer value = _bindings.spine_event_get_string_value(_event).cast(); + return value.toDartString(); + } + + void setStringValue(String value) { + final nativeString = value.toNativeUtf8(allocator: _allocator); + _bindings.spine_event_set_string_value(_event, nativeString.cast()); + _allocator.free(nativeString); + } + + double getVolume() { + return _bindings.spine_event_get_volume(_event); + } + + void setVolume(double volume) { + _bindings.spine_event_set_volume(_event, volume); + } + + double getBalance() { + return _bindings.spine_event_get_balance(_event); + } + + void setBalance(double balance) { + _bindings.spine_event_set_balance(_event, balance); + } +} + +/// The callback to implement for receiving [TrackEntry] events. It is always safe to call [AnimationState] methods when receiving +/// events. +/// +/// TrackEntry events are collected during [AnimationState.update] and [AnimationState.apply] and +/// fired only after those methods are finished. +/// +/// See [TrackEntry.setListener] and [AnimationState.setListener]. +typedef AnimationStateListener = void Function(EventType type, TrackEntry entry, Event? event); + +/// Stores mix (crossfade) durations to be applied when {@link AnimationState} animations are changed. +class AnimationStateData { + final spine_animation_state_data _data; + + AnimationStateData._(this._data); + + /// The SkeletonData to look up animations when they are specified by name. + SkeletonData getSkeletonData() { + return SkeletonData._(_bindings.spine_animation_state_data_get_skeleton_data(_data)); + } + + double getDefaultMix() { + return _bindings.spine_animation_state_data_get_default_mix(_data); + } + + void setDefaultMix(double defaultMix) { + _bindings.spine_animation_state_data_set_default_mix(_data, defaultMix); + } + + /// Sets a mix duration by animation name. + /// + /// See [setMix]. + void setMixByName(String fromName, String toName, double duration) { + final fromNative = fromName.toNativeUtf8(allocator: _allocator); + final toNative = toName.toNativeUtf8(allocator: _allocator); + _bindings.spine_animation_state_data_set_mix_by_name(_data, fromNative.cast(), toNative.cast(), duration); + _allocator.free(fromNative); + _allocator.free(toNative); + } + + /// Returns the mix duration to use when changing from the specified animation to the other, or the [getDefaultMix] if + /// no mix duration has been set. + double getMixByName(String fromName, String toName) { + final fromNative = fromName.toNativeUtf8(allocator: _allocator); + final toNative = toName.toNativeUtf8(allocator: _allocator); + final duration = _bindings.spine_animation_state_data_get_mix_by_name(_data, fromNative.cast(), toNative.cast()); + _allocator.free(fromNative); + _allocator.free(toNative); + return duration; + } + + /// Sets the mix duration when changing from the specified animation to the other. + /// + /// See [TrackEntry.mixDuration]. + Future setMix(Animation from, Animation to, double duration) async { + _bindings.spine_animation_state_data_set_mix(_data, from._animation, to._animation, duration); + } + + /// Returns the mix duration to use when changing from the specified animation to the other, or the [getDefaultMix] if + /// no mix duration has been set. + double getMix(Animation from, Animation to) { + return _bindings.spine_animation_state_data_get_mix(_data, from._animation, to._animation); + } + + /// Removes all mix durations. + void clear() { + _bindings.spine_animation_state_data_clear(_data); + } +} + +/// Applies animations over time, queues animations for later playback, mixes (crossfading) between animations, and applies +/// multiple animations on top of each other (layering). +/// +/// See Applying Animations in the Spine Runtimes Guide. +class AnimationState { + final spine_animation_state _state; + final spine_animation_state_events _events; + final Map _trackEntryListeners; + AnimationStateListener? _stateListener; + + AnimationState._(this._state, this._events) : _trackEntryListeners = {}; + + void _setTrackEntryListener(spine_track_entry entry, AnimationStateListener? listener) { + if (listener == null) { + _trackEntryListeners.remove(entry); + } else { + _trackEntryListeners[entry] = listener; + } + } + + /// Increments each track entry [TrackEntry.getTrackTime], setting queued animations as current if needed. + void update(double delta) { + _bindings.spine_animation_state_update(_state, delta); + + final numEvents = _bindings.spine_animation_state_events_get_num_events(_events); + if (numEvents > 0) { + for (int i = 0; i < numEvents; i++) { + late final EventType type; + switch (_bindings.spine_animation_state_events_get_event_type(_events, i)) { + case 0: + type = EventType.start; + break; + case 1: + type = EventType.interrupt; + break; + case 2: + type = EventType.end; + break; + case 3: + type = EventType.complete; + break; + case 4: + type = EventType.dispose; + break; + case 5: + type = EventType.event; + break; + } + final nativeEntry = _bindings.spine_animation_state_events_get_track_entry(_events, i); + final entry = TrackEntry._(nativeEntry, this); + final nativeEvent = _bindings.spine_animation_state_events_get_event(_events, i); + final event = nativeEvent.address == nullptr.address ? null : Event._(nativeEvent); + if (_trackEntryListeners.containsKey(nativeEntry)) { + _trackEntryListeners[entry]?.call(type, entry, event); + } + if (_stateListener != null) { + _stateListener?.call(type, entry, event); + } + if (type == EventType.dispose) { + _bindings.spine_animation_state_dispose_track_entry(_state, nativeEntry); + } + } + } + _bindings.spine_animation_state_events_reset(_events); + } + + /// Poses the skeleton using the track entry animations. The animation state is not changed, so can be applied to multiple + /// skeletons to pose them identically. + /// + /// Returns true if any animations were applied. + void apply(Skeleton skeleton) { + _bindings.spine_animation_state_apply(_state, skeleton._skeleton); + } + + /// Removes all animations from all tracks, leaving skeletons in their current pose. + /// + /// It may be desired to use [setEmptyAnimations] to mix the skeletons back to the setup pose, + /// rather than leaving them in their current pose. + void clearTracks() { + _bindings.spine_animation_state_clear_tracks(_state); + } + + /// Removes all animations from the track, leaving skeletons in their current pose. + /// + /// It may be desired to use [setEmptyAnimations] to mix the skeletons back to the setup pose, + /// rather than leaving them in their current pose. + void clearTrack(int trackIndex) { + _bindings.spine_animation_state_clear_track(_state, trackIndex); + } + + /// Sets an animation by name. + /// + /// See [setAnimation]. + TrackEntry setAnimationByName(int trackIndex, String animationName, bool loop) { + final animation = animationName.toNativeUtf8(allocator: _allocator); + final entry = _bindings.spine_animation_state_set_animation_by_name(_state, trackIndex, animation.cast(), loop ? -1 : 0); + _allocator.free(animation); + if (entry.address == nullptr.address) throw Exception("Couldn't set animation $animationName"); + return TrackEntry._(entry, this); + } + + /// Sets the current [animation] for a track at [trackIndex], discarding any queued animations. If the formerly current track entry was never + /// applied to a skeleton, it is replaced (not mixed from). + /// + /// If [loop] is true, the animation will repeat. If false it will not, instead its last frame is applied if played beyond its + /// duration. In either case [TrackEntry.getTrackEnd] determines when the track is cleared. + /// + /// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept + /// after the [EventType.dispose] event occurs. + TrackEntry setAnimation(int trackIndex, Animation animation, bool loop) { + final entry = _bindings.spine_animation_state_set_animation(_state, trackIndex, animation._animation, loop ? -1 : 0); + if (entry.address == nullptr.address) throw Exception("Couldn't set animation ${animation.getName()}"); + return TrackEntry._(entry, this); + } + + /// Queues an animation by name. + /// + /// See [addAnimation]. + TrackEntry addAnimationByName(int trackIndex, String animationName, bool loop, double delay) { + final animation = animationName.toNativeUtf8(allocator: _allocator); + final entry = _bindings.spine_animation_state_add_animation_by_name(_state, trackIndex, animation.cast(), loop ? -1 : 0, delay); + _allocator.free(animation); + if (entry.address == nullptr.address) throw Exception("Couldn't add animation $animationName"); + return TrackEntry._(entry, this); + } + + /// Adds an [animation] to be played after the current or last queued animation for a track at [trackIndex]. If the track is empty, it is + /// equivalent to calling [setAnimation]. + /// + /// If [delay] > 0, sets [TrackEntry.getDelay]. If [delay] <= 0, the delay set is the duration of the previous track entry + /// minus any mix duration (from the [AnimationStateData]) plus the specified delay (ie the mix + /// ends at (delay = 0) or before (delay < 0) the previous track entry duration). If the + /// previous entry is looping, its next loop completion is used instead of its duration. + /// + /// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept + /// after the [EventType.dispose] event occurs. + TrackEntry addAnimation(int trackIndex, Animation animation, bool loop, double delay) { + final entry = _bindings.spine_animation_state_add_animation(_state, trackIndex, animation._animation, loop ? -1 : 0, delay); + if (entry.address == nullptr.address) throw Exception("Couldn't add animation ${animation.getName()}"); + return TrackEntry._(entry, this); + } + + /// Sets an empty animation for a track at [trackIndex], discarding any queued animations, and sets the track entry's + /// [TrackEntry.getMixDuration] to [mixDuration]. An empty animation has no timelines and serves as a placeholder for mixing in or out. + /// + /// Mixing out is done by setting an empty animation with a mix duration using either [setEmptyAnimation], + /// [setEmptyAnimations], or [addEmptyAnimation]. Mixing to an empty animation causes + /// the previous animation to be applied less and less over the mix duration. Properties keyed in the previous animation + /// transition to the value from lower tracks or to the setup pose value if no lower tracks key the property. A mix duration of + /// 0 still mixes out over one frame. + /// + /// Mixing in is done by first setting an empty animation, then adding an animation using + /// [addAnimation] with the desired delay (an empty animation has a duration of 0) and on + /// the returned track entry, set the [TrackEntry.setMixDuration]. Mixing from an empty animation causes the new + /// animation to be applied more and more over the mix duration. Properties keyed in the new animation transition from the value + /// from lower tracks or from the setup pose value if no lower tracks key the property to the value keyed in the new + /// animation. + TrackEntry setEmptyAnimation(int trackIndex, double mixDuration) { + final entry = _bindings.spine_animation_state_set_empty_animation(_state, trackIndex, mixDuration); + return TrackEntry._(entry, this); + } + + /// Adds an empty animation to be played after the current or last queued animation for a track, and sets the track entry's + /// [TrackEntry.getMixDuration]. If the track is empty, it is equivalent to calling + /// [setEmptyAnimation]. + /// + /// See [setEmptyAnimation]. + /// + /// If [delay] > 0, sets [TrackEntry.getDelay]. If <= 0, the delay set is the duration of the previous track entry + /// minus any mix duration plus the specified delay (ie the mix ends at (delay = 0) or + /// before (delay < 0) the previous track entry duration). If the previous entry is looping, its next + /// loop completion is used instead of its duration. + /// + /// Returns a track entry to allow further customization of animation playback. References to the track entry must not be kept + /// after the [EventType.dispose] event occurs. + TrackEntry addEmptyAnimation(int trackIndex, double mixDuration, double delay) { + final entry = _bindings.spine_animation_state_add_empty_animation(_state, trackIndex, mixDuration, delay); + return TrackEntry._(entry, this); + } + + /// Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. + TrackEntry? getCurrent(int trackIndex) { + final entry = _bindings.spine_animation_state_get_current(_state, trackIndex); + if (entry.address == nullptr.address) return null; + return TrackEntry._(entry, this); + } + + /// Returns the number of tracks that have animations queued. + int getNumTracks() { + return _bindings.spine_animation_state_get_num_tracks(_state); + } + + /// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix + /// duration. + void setEmptyAnimations(double mixDuration) { + _bindings.spine_animation_state_set_empty_animations(_state, mixDuration); + } + + /// Multiplier for the delta time when the animation state is updated, causing time for all animations and mixes to play slower + /// or faster. Defaults to 1. + /// + /// See [TrackEntry.getTimeScale] for affecting a single animation. + double getTimeScale() { + return _bindings.spine_animation_state_get_time_scale(_state); + } + + void setTimeScale(double timeScale) { + _bindings.spine_animation_state_set_time_scale(_state, timeScale); + } + + /// The [AnimationStateData] to look up mix durations. + AnimationStateData getData() { + return AnimationStateData._(_bindings.spine_animation_state_get_data(_state)); + } + + /// The listener for events generated for all tracks managed by the AnimationState, or null. + /// + /// A track entry returned from [setAnimation] is already the current animation + /// for the track, so the track entry listener will not be called for [EventType.start]. + void setListener(AnimationStateListener? listener) { + _stateListener = listener; + } +} + +/// A SkeletonDrawable bundles loading, updating, and rendering an [Atlas], [Skeleton], and [AnimationState] +/// into a single easy to use class. +/// +/// Use the [fromAsset], [fromFile], or [fromHttp] methods to construct a SkeletonDrawable. To have +/// multiple skeleton drawable instances share the same [Atlas] and [SkeletonData], use the constructor. +/// +/// You can then directly access the [atlas], [skeletonData], [skeleton], [animationStateData], and [animationState] +/// to query and animate the skeleton. Use the [AnimationState] to queue animations on one or more tracks +/// via [AnimationState.setAnimation] or [AnimationState.addAnimation]. +/// +/// To update the [AnimationState] and apply it to the [Skeleton] call the [update] function, providing it +/// a delta time in seconds to advance the animations. +/// +/// To render the current pose of the [Skeleton], use the rendering methods [render], [renderToCanvas], [renderToPictureRecorder], +/// [renderToPng], or [renderToRawImageData], depending on your needs. +/// +/// When the skeleton drawable is no longer needed, call the [dispose] method to release its resources. If +/// the skeleton drawable was constructed from a shared [Atlas] and [SkeletonData], make sure to dispose the +/// atlas and skeleton data as well, if no skeleton drawable references them anymore. +class SkeletonDrawable { + final Atlas atlas; + final SkeletonData skeletonData; + late final spine_skeleton_drawable _drawable; + late final Skeleton skeleton; + late final AnimationStateData animationStateData; + late final AnimationState animationState; + final bool _ownsAtlasAndSkeletonData; + bool _disposed; + + /// Constructs a new skeleton drawable from the given (possibly shared) [Atlas] and [SkeletonData]. If + /// the atlas and skeleton data are not shared, the drawable can take ownership by passing true for [_ownsAtlasAndSkeletonData]. + /// In that case a call to [dispose] will also dispose the atlas and skeleton data. + SkeletonDrawable(this.atlas, this.skeletonData, this._ownsAtlasAndSkeletonData) : _disposed = false { + _drawable = _bindings.spine_skeleton_drawable_create(skeletonData._data); + skeleton = Skeleton._(_bindings.spine_skeleton_drawable_get_skeleton(_drawable)); + animationStateData = AnimationStateData._(_bindings.spine_skeleton_drawable_get_animation_state_data(_drawable)); + animationState = AnimationState._(_bindings.spine_skeleton_drawable_get_animation_state(_drawable), + _bindings.spine_skeleton_drawable_get_animation_state_events(_drawable)); + skeleton.updateWorldTransform(); + } + + /// Constructs a new skeleton drawable from the [atlasFile] and [skeletonFile] from the root asset bundle + /// or the optionally provided [bundle]. + /// + /// Throws an exception in case the data could not be loaded. + static Future fromAsset(String atlasFile, String skeletonFile, {AssetBundle? bundle}) async { + bundle ??= rootBundle; + var atlas = await Atlas.fromAsset(atlasFile, bundle: bundle); + var skeletonData = await SkeletonData.fromAsset(atlas, skeletonFile, bundle: bundle); + return SkeletonDrawable(atlas, skeletonData, true); + } + + /// Constructs a new skeleton drawable from the [atlasFile] and [skeletonFile]. + /// + /// Throws an exception in case the data could not be loaded. + static Future fromFile(String atlasFile, String skeletonFile) async { + var atlas = await Atlas.fromFile(atlasFile); + var skeletonData = await SkeletonData.fromFile(atlas, skeletonFile); + return SkeletonDrawable(atlas, skeletonData, true); + } + + /// Constructs a new skeleton drawable from the [atlasUrl] and [skeletonUrl]. + /// + /// Throws an exception in case the data could not be loaded. + static Future fromHttp(String atlasUrl, String skeletonUrl) async { + var atlas = await Atlas.fromHttp(atlasUrl); + var skeletonData = await SkeletonData.fromHttp(atlas, skeletonUrl); + return SkeletonDrawable(atlas, skeletonData, true); + } + + /// Updates the [AnimationState] using the [delta] time given in seconds, applies the + /// animation state to the [Skeleton] and updates the world transforms of the skeleton + /// to calculate its current pose. + void update(double delta) { + if (_disposed) return; + animationState.update(delta); + animationState.apply(skeleton); + skeleton.updateWorldTransform(); + } + + /// Renders to current skeleton pose to a list of [RenderCommand] instances. The render commands + /// can be rendered via [Canvas.drawVertices]. + List render() { + if (_disposed) return []; + spine_render_command nativeCmd = _bindings.spine_skeleton_drawable_render(_drawable); + List commands = []; + while (nativeCmd.address != nullptr.address) { + final atlasPage = atlas.atlasPages[_bindings.spine_render_command_get_atlas_page(nativeCmd)]; + commands.add(RenderCommand._(nativeCmd, atlasPage.width.toDouble(), atlasPage.height.toDouble())); + nativeCmd = _bindings.spine_render_command_get_next(nativeCmd); + } + return commands; + } + + /// Renders the skeleton drawable's current pose to the given [canvas]. Does not perform any + /// scaling or fitting. + void renderToCanvas(Canvas canvas) { + var commands = render(); + for (final cmd in commands) { + canvas.drawVertices(cmd.vertices, rendering.BlendMode.modulate, atlas.atlasPagePaints[cmd.atlasPageIndex]); + } + } + + /// Renders the skeleton drawable's current pose to a [PictureRecorder] with the given [width] and [height]. + /// Uses [bgColor], a 32-bit ARGB color value, to paint the background. + /// Scales and centers the skeleton to fit the within the bounds of [width] and [height]. + PictureRecorder renderToPictureRecorder(double width, double height, int bgColor) { + var bounds = skeleton.getBounds(); + var scale = 1 / (bounds.width > bounds.height ? bounds.width / width : bounds.height / height); + + var recorder = PictureRecorder(); + var canvas = Canvas(recorder); + var paint = Paint() + ..color = material.Color(bgColor) + ..style = PaintingStyle.fill; + canvas.drawRect(Rect.fromLTWH(0, 0, width, height), paint); + canvas.translate(width / 2, height / 2); + canvas.scale(scale, scale); + canvas.translate(-(bounds.x + bounds.width / 2), -(bounds.y + bounds.height / 2)); + canvas.drawRect(const Rect.fromLTRB(-5, -5, 5, -5), paint..color = material.Colors.red); + renderToCanvas(canvas); + return recorder; + } + + /// Renders the skeleton drawable's current pose to a PNG encoded in a [Uint8List], with the given [width] and [height]. + /// Uses [bgColor], a 32-bit ARGB color value, to paint the background. + /// Scales and centers the skeleton to fit the within the bounds of [width] and [height]. + Future renderToPng(double width, double height, int bgColor) async { + final recorder = renderToPictureRecorder(width, height, bgColor); + final image = await recorder.endRecording().toImage(width.toInt(), height.toInt()); + return (await image.toByteData(format: ImageByteFormat.png))!.buffer.asUint8List(); + } + + /// Renders the skeleton drawable's current pose to a [RawImageData], with the given [width] and [height]. + /// Uses [bgColor], a 32-bit ARGB color value, to paint the background. + /// Scales and centers the skeleton to fit the within the bounds of [width] and [height]. + Future renderToRawImageData(double width, double height, int bgColor) async { + final recorder = renderToPictureRecorder(width, height, bgColor); + var rawImageData = + (await (await recorder.endRecording().toImage(width.toInt(), height.toInt())).toByteData(format: ImageByteFormat.rawRgba))! + .buffer + .asUint8List(); + return RawImageData(rawImageData, width.toInt(), height.toInt()); + } + + /// Disposes the skeleton drawable's resources. If the skeleton drawable owns the atlas + /// and skeleton data, they are disposed as well. Must be called when the skeleton drawable + /// is no longer in use. + void dispose() { + if (_disposed) return; + _disposed = true; + if (_ownsAtlasAndSkeletonData) { + atlas.dispose(); + skeletonData.dispose(); + } + _bindings.spine_skeleton_drawable_dispose(_drawable); + } +} + +/// Stores the vertices, indices, and atlas page index to be used for rendering one or more attachments +/// of a [Skeleton] to a [Canvas]. See the implementation of [SkeletonDrawable.renderToCanvas] on how to use this data to render it to a +/// [Canvas]. +class RenderCommand { + late final Vertices vertices; + late final int atlasPageIndex; + late final Float32List positions; + late final Float32List uvs; + late final Int32List colors; + late final Uint16List indices; + + RenderCommand._(spine_render_command nativeCmd, double pageWidth, double pageHeight) { + atlasPageIndex = _bindings.spine_render_command_get_atlas_page(nativeCmd); + int numVertices = _bindings.spine_render_command_get_num_vertices(nativeCmd); + int numIndices = _bindings.spine_render_command_get_num_indices(nativeCmd); + positions = _bindings.spine_render_command_get_positions(nativeCmd).asTypedList(numVertices * 2); + uvs = _bindings.spine_render_command_get_uvs(nativeCmd).asTypedList(numVertices * 2); + for (int i = 0; i < numVertices * 2; i += 2) { + uvs[i] *= pageWidth; + uvs[i + 1] *= pageHeight; + } + colors = _bindings.spine_render_command_get_colors(nativeCmd).asTypedList(numVertices); + indices = _bindings.spine_render_command_get_indices(nativeCmd).asTypedList(numIndices); + + if (!kIsWeb) { + // We pass the native data as views directly to Vertices.raw. According to the sources, the data + // is copied, so it doesn't matter that we free up the underlying memory on the next + // render call. See the implementation of Vertices.raw() here: + // https://github.com/flutter/engine/blob/5c60785b802ad2c8b8899608d949342d5c624952/lib/ui/painting/vertices.cc#L21 + vertices = Vertices.raw(VertexMode.triangles, positions, textureCoordinates: uvs, colors: colors, indices: indices); + } else { + // On the web, rendering is done through CanvasKit, which requires copies of the native data. + final positionsCopy = Float32List.fromList(positions); + final uvsCopy = Float32List.fromList(uvs); + final colorsCopy = Int32List.fromList(colors); + final indicesCopy = Uint16List.fromList(indices); + vertices = Vertices.raw(VertexMode.triangles, positionsCopy, textureCoordinates: uvsCopy, colors: colorsCopy, indices: indicesCopy); + } + } +} + +/// Renders debug information for a [SkeletonDrawable], like bone locations, to a [Canvas]. +/// See [DebugRenderer.render]. +class DebugRenderer { + const DebugRenderer(); + + void render(SkeletonDrawable drawable, Canvas canvas, List commands) { + final bonePaint = Paint() + ..color = material.Colors.blue + ..style = PaintingStyle.fill; + for (final bone in drawable.skeleton.getBones()) { + canvas.drawRect(Rect.fromCenter(center: Offset(bone.getWorldX(), bone.getWorldY()), width: 5, height: 5), bonePaint); + } + } +} diff --git a/spine-flutter/lib/spine_flutter_bindings_generated.dart b/spine-flutter/lib/spine_flutter_bindings_generated.dart new file mode 100644 index 000000000..83519f8b5 --- /dev/null +++ b/spine-flutter/lib/spine_flutter_bindings_generated.dart @@ -0,0 +1,10177 @@ +// ignore_for_file: always_specify_types, constant_identifier_names +// ignore_for_file: camel_case_types +// ignore_for_file: non_constant_identifier_names + +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +import 'ffi_proxy.dart' as ffi; + +/// Bindings for `src/spine_flutter.h`. +/// +/// Regenerate bindings with `dart run ffigen --config ffigen.yaml`. +/// +class SpineFlutterBindings { + /// Holds the symbol lookup function. + final ffi.Pointer Function(String symbolName) + _lookup; + + /// The symbols are looked up in [dynamicLibrary]. + SpineFlutterBindings(ffi.DynamicLibrary dynamicLibrary) + : _lookup = dynamicLibrary.lookup; + + /// The symbols are looked up with [lookup]. + SpineFlutterBindings.fromLookup( + ffi.Pointer Function(String symbolName) + lookup) + : _lookup = lookup; + + int spine_major_version() { + return _spine_major_version(); + } + + late final _spine_major_versionPtr = + _lookup>('spine_major_version'); + late final _spine_major_version = + _spine_major_versionPtr.asFunction(); + + int spine_minor_version() { + return _spine_minor_version(); + } + + late final _spine_minor_versionPtr = + _lookup>('spine_minor_version'); + late final _spine_minor_version = + _spine_minor_versionPtr.asFunction(); + + void spine_enable_debug_extension( + int enable, + ) { + return _spine_enable_debug_extension( + enable, + ); + } + + late final _spine_enable_debug_extensionPtr = + _lookup>( + 'spine_enable_debug_extension'); + late final _spine_enable_debug_extension = + _spine_enable_debug_extensionPtr.asFunction(); + + void spine_report_leaks() { + return _spine_report_leaks(); + } + + late final _spine_report_leaksPtr = + _lookup>('spine_report_leaks'); + late final _spine_report_leaks = + _spine_report_leaksPtr.asFunction(); + + double spine_color_get_r( + spine_color color, + ) { + return _spine_color_get_r( + color, + ); + } + + late final _spine_color_get_rPtr = + _lookup>( + 'spine_color_get_r'); + late final _spine_color_get_r = + _spine_color_get_rPtr.asFunction(); + + double spine_color_get_g( + spine_color color, + ) { + return _spine_color_get_g( + color, + ); + } + + late final _spine_color_get_gPtr = + _lookup>( + 'spine_color_get_g'); + late final _spine_color_get_g = + _spine_color_get_gPtr.asFunction(); + + double spine_color_get_b( + spine_color color, + ) { + return _spine_color_get_b( + color, + ); + } + + late final _spine_color_get_bPtr = + _lookup>( + 'spine_color_get_b'); + late final _spine_color_get_b = + _spine_color_get_bPtr.asFunction(); + + double spine_color_get_a( + spine_color color, + ) { + return _spine_color_get_a( + color, + ); + } + + late final _spine_color_get_aPtr = + _lookup>( + 'spine_color_get_a'); + late final _spine_color_get_a = + _spine_color_get_aPtr.asFunction(); + + double spine_bounds_get_x( + spine_bounds bounds, + ) { + return _spine_bounds_get_x( + bounds, + ); + } + + late final _spine_bounds_get_xPtr = + _lookup>( + 'spine_bounds_get_x'); + late final _spine_bounds_get_x = + _spine_bounds_get_xPtr.asFunction(); + + double spine_bounds_get_y( + spine_bounds bounds, + ) { + return _spine_bounds_get_y( + bounds, + ); + } + + late final _spine_bounds_get_yPtr = + _lookup>( + 'spine_bounds_get_y'); + late final _spine_bounds_get_y = + _spine_bounds_get_yPtr.asFunction(); + + double spine_bounds_get_width( + spine_bounds bounds, + ) { + return _spine_bounds_get_width( + bounds, + ); + } + + late final _spine_bounds_get_widthPtr = + _lookup>( + 'spine_bounds_get_width'); + late final _spine_bounds_get_width = + _spine_bounds_get_widthPtr.asFunction(); + + double spine_bounds_get_height( + spine_bounds bounds, + ) { + return _spine_bounds_get_height( + bounds, + ); + } + + late final _spine_bounds_get_heightPtr = + _lookup>( + 'spine_bounds_get_height'); + late final _spine_bounds_get_height = + _spine_bounds_get_heightPtr.asFunction(); + + double spine_vector_get_x( + spine_vector vector, + ) { + return _spine_vector_get_x( + vector, + ); + } + + late final _spine_vector_get_xPtr = + _lookup>( + 'spine_vector_get_x'); + late final _spine_vector_get_x = + _spine_vector_get_xPtr.asFunction(); + + double spine_vector_get_y( + spine_vector vector, + ) { + return _spine_vector_get_y( + vector, + ); + } + + late final _spine_vector_get_yPtr = + _lookup>( + 'spine_vector_get_y'); + late final _spine_vector_get_y = + _spine_vector_get_yPtr.asFunction(); + + spine_atlas spine_atlas_load( + ffi.Pointer atlasData, + ) { + return _spine_atlas_load( + atlasData, + ); + } + + late final _spine_atlas_loadPtr = + _lookup)>>( + 'spine_atlas_load'); + late final _spine_atlas_load = _spine_atlas_loadPtr + .asFunction)>(); + + int spine_atlas_get_num_image_paths( + spine_atlas atlas, + ) { + return _spine_atlas_get_num_image_paths( + atlas, + ); + } + + late final _spine_atlas_get_num_image_pathsPtr = + _lookup>( + 'spine_atlas_get_num_image_paths'); + late final _spine_atlas_get_num_image_paths = + _spine_atlas_get_num_image_pathsPtr + .asFunction(); + + ffi.Pointer spine_atlas_get_image_path( + spine_atlas atlas, + int index, + ) { + return _spine_atlas_get_image_path( + atlas, + index, + ); + } + + late final _spine_atlas_get_image_pathPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_atlas, ffi.Int32)>>('spine_atlas_get_image_path'); + late final _spine_atlas_get_image_path = _spine_atlas_get_image_pathPtr + .asFunction Function(spine_atlas, int)>(); + + ffi.Pointer spine_atlas_get_error( + spine_atlas atlas, + ) { + return _spine_atlas_get_error( + atlas, + ); + } + + late final _spine_atlas_get_errorPtr = + _lookup Function(spine_atlas)>>( + 'spine_atlas_get_error'); + late final _spine_atlas_get_error = _spine_atlas_get_errorPtr + .asFunction Function(spine_atlas)>(); + + void spine_atlas_dispose( + spine_atlas atlas, + ) { + return _spine_atlas_dispose( + atlas, + ); + } + + late final _spine_atlas_disposePtr = + _lookup>( + 'spine_atlas_dispose'); + late final _spine_atlas_dispose = + _spine_atlas_disposePtr.asFunction(); + + spine_skeleton_data_result spine_skeleton_data_load_json( + spine_atlas atlas, + ffi.Pointer skeletonData, + ) { + return _spine_skeleton_data_load_json( + atlas, + skeletonData, + ); + } + + late final _spine_skeleton_data_load_jsonPtr = _lookup< + ffi.NativeFunction< + spine_skeleton_data_result Function(spine_atlas, + ffi.Pointer)>>('spine_skeleton_data_load_json'); + late final _spine_skeleton_data_load_json = + _spine_skeleton_data_load_jsonPtr.asFunction< + spine_skeleton_data_result Function( + spine_atlas, ffi.Pointer)>(); + + spine_skeleton_data_result spine_skeleton_data_load_binary( + spine_atlas atlas, + ffi.Pointer skeletonData, + int length, + ) { + return _spine_skeleton_data_load_binary( + atlas, + skeletonData, + length, + ); + } + + late final _spine_skeleton_data_load_binaryPtr = _lookup< + ffi.NativeFunction< + spine_skeleton_data_result Function( + spine_atlas, + ffi.Pointer, + ffi.Int32)>>('spine_skeleton_data_load_binary'); + late final _spine_skeleton_data_load_binary = + _spine_skeleton_data_load_binaryPtr.asFunction< + spine_skeleton_data_result Function( + spine_atlas, ffi.Pointer, int)>(); + + ffi.Pointer spine_skeleton_data_result_get_error( + spine_skeleton_data_result result, + ) { + return _spine_skeleton_data_result_get_error( + result, + ); + } + + late final _spine_skeleton_data_result_get_errorPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function(spine_skeleton_data_result)>>( + 'spine_skeleton_data_result_get_error'); + late final _spine_skeleton_data_result_get_error = + _spine_skeleton_data_result_get_errorPtr + .asFunction Function(spine_skeleton_data_result)>(); + + spine_skeleton_data spine_skeleton_data_result_get_data( + spine_skeleton_data_result result, + ) { + return _spine_skeleton_data_result_get_data( + result, + ); + } + + late final _spine_skeleton_data_result_get_dataPtr = _lookup< + ffi.NativeFunction< + spine_skeleton_data Function(spine_skeleton_data_result)>>( + 'spine_skeleton_data_result_get_data'); + late final _spine_skeleton_data_result_get_data = + _spine_skeleton_data_result_get_dataPtr.asFunction< + spine_skeleton_data Function(spine_skeleton_data_result)>(); + + void spine_skeleton_data_result_dispose( + spine_skeleton_data_result result, + ) { + return _spine_skeleton_data_result_dispose( + result, + ); + } + + late final _spine_skeleton_data_result_disposePtr = _lookup< + ffi.NativeFunction>( + 'spine_skeleton_data_result_dispose'); + late final _spine_skeleton_data_result_dispose = + _spine_skeleton_data_result_disposePtr + .asFunction(); + + spine_bone_data spine_skeleton_data_find_bone( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_bone( + data, + name, + ); + } + + late final _spine_skeleton_data_find_bonePtr = _lookup< + ffi.NativeFunction< + spine_bone_data Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_bone'); + late final _spine_skeleton_data_find_bone = + _spine_skeleton_data_find_bonePtr.asFunction< + spine_bone_data Function(spine_skeleton_data, ffi.Pointer)>(); + + spine_slot_data spine_skeleton_data_find_slot( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_slot( + data, + name, + ); + } + + late final _spine_skeleton_data_find_slotPtr = _lookup< + ffi.NativeFunction< + spine_slot_data Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_slot'); + late final _spine_skeleton_data_find_slot = + _spine_skeleton_data_find_slotPtr.asFunction< + spine_slot_data Function(spine_skeleton_data, ffi.Pointer)>(); + + spine_skin spine_skeleton_data_find_skin( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_skin( + data, + name, + ); + } + + late final _spine_skeleton_data_find_skinPtr = _lookup< + ffi.NativeFunction< + spine_skin Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_skin'); + late final _spine_skeleton_data_find_skin = + _spine_skeleton_data_find_skinPtr.asFunction< + spine_skin Function(spine_skeleton_data, ffi.Pointer)>(); + + spine_event_data spine_skeleton_data_find_event( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_event( + data, + name, + ); + } + + late final _spine_skeleton_data_find_eventPtr = _lookup< + ffi.NativeFunction< + spine_event_data Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_event'); + late final _spine_skeleton_data_find_event = + _spine_skeleton_data_find_eventPtr.asFunction< + spine_event_data Function(spine_skeleton_data, ffi.Pointer)>(); + + spine_animation spine_skeleton_data_find_animation( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_animation( + data, + name, + ); + } + + late final _spine_skeleton_data_find_animationPtr = _lookup< + ffi.NativeFunction< + spine_animation Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_animation'); + late final _spine_skeleton_data_find_animation = + _spine_skeleton_data_find_animationPtr.asFunction< + spine_animation Function(spine_skeleton_data, ffi.Pointer)>(); + + spine_ik_constraint_data spine_skeleton_data_find_ik_constraint( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_ik_constraint( + data, + name, + ); + } + + late final _spine_skeleton_data_find_ik_constraintPtr = _lookup< + ffi.NativeFunction< + spine_ik_constraint_data Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_ik_constraint'); + late final _spine_skeleton_data_find_ik_constraint = + _spine_skeleton_data_find_ik_constraintPtr.asFunction< + spine_ik_constraint_data Function( + spine_skeleton_data, ffi.Pointer)>(); + + spine_transform_constraint_data spine_skeleton_data_find_transform_constraint( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_transform_constraint( + data, + name, + ); + } + + late final _spine_skeleton_data_find_transform_constraintPtr = _lookup< + ffi.NativeFunction< + spine_transform_constraint_data Function( + spine_skeleton_data, ffi.Pointer)>>( + 'spine_skeleton_data_find_transform_constraint'); + late final _spine_skeleton_data_find_transform_constraint = + _spine_skeleton_data_find_transform_constraintPtr.asFunction< + spine_transform_constraint_data Function( + spine_skeleton_data, ffi.Pointer)>(); + + spine_path_constraint_data spine_skeleton_data_find_path_constraint( + spine_skeleton_data data, + ffi.Pointer name, + ) { + return _spine_skeleton_data_find_path_constraint( + data, + name, + ); + } + + late final _spine_skeleton_data_find_path_constraintPtr = _lookup< + ffi.NativeFunction< + spine_path_constraint_data Function(spine_skeleton_data, + ffi.Pointer)>>('spine_skeleton_data_find_path_constraint'); + late final _spine_skeleton_data_find_path_constraint = + _spine_skeleton_data_find_path_constraintPtr.asFunction< + spine_path_constraint_data Function( + spine_skeleton_data, ffi.Pointer)>(); + + ffi.Pointer spine_skeleton_data_get_name( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_name( + data, + ); + } + + late final _spine_skeleton_data_get_namePtr = _lookup< + ffi.NativeFunction Function(spine_skeleton_data)>>( + 'spine_skeleton_data_get_name'); + late final _spine_skeleton_data_get_name = _spine_skeleton_data_get_namePtr + .asFunction Function(spine_skeleton_data)>(); + + /// OMITTED setName() + int spine_skeleton_data_get_num_bones( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_bones( + data, + ); + } + + late final _spine_skeleton_data_get_num_bonesPtr = + _lookup>( + 'spine_skeleton_data_get_num_bones'); + late final _spine_skeleton_data_get_num_bones = + _spine_skeleton_data_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_bones( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_bones( + data, + ); + } + + late final _spine_skeleton_data_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>('spine_skeleton_data_get_bones'); + late final _spine_skeleton_data_get_bones = _spine_skeleton_data_get_bonesPtr + .asFunction Function(spine_skeleton_data)>(); + + int spine_skeleton_data_get_num_slots( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_slots( + data, + ); + } + + late final _spine_skeleton_data_get_num_slotsPtr = + _lookup>( + 'spine_skeleton_data_get_num_slots'); + late final _spine_skeleton_data_get_num_slots = + _spine_skeleton_data_get_num_slotsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_slots( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_slots( + data, + ); + } + + late final _spine_skeleton_data_get_slotsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>('spine_skeleton_data_get_slots'); + late final _spine_skeleton_data_get_slots = _spine_skeleton_data_get_slotsPtr + .asFunction Function(spine_skeleton_data)>(); + + int spine_skeleton_data_get_num_skins( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_skins( + data, + ); + } + + late final _spine_skeleton_data_get_num_skinsPtr = + _lookup>( + 'spine_skeleton_data_get_num_skins'); + late final _spine_skeleton_data_get_num_skins = + _spine_skeleton_data_get_num_skinsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_skins( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_skins( + data, + ); + } + + late final _spine_skeleton_data_get_skinsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>('spine_skeleton_data_get_skins'); + late final _spine_skeleton_data_get_skins = _spine_skeleton_data_get_skinsPtr + .asFunction Function(spine_skeleton_data)>(); + + spine_skin spine_skeleton_data_get_default_skin( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_default_skin( + data, + ); + } + + late final _spine_skeleton_data_get_default_skinPtr = + _lookup>( + 'spine_skeleton_data_get_default_skin'); + late final _spine_skeleton_data_get_default_skin = + _spine_skeleton_data_get_default_skinPtr + .asFunction(); + + void spine_skeleton_data_set_default_skin( + spine_skeleton_data data, + spine_skin skin, + ) { + return _spine_skeleton_data_set_default_skin( + data, + skin, + ); + } + + late final _spine_skeleton_data_set_default_skinPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton_data, + spine_skin)>>('spine_skeleton_data_set_default_skin'); + late final _spine_skeleton_data_set_default_skin = + _spine_skeleton_data_set_default_skinPtr + .asFunction(); + + int spine_skeleton_data_get_num_events( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_events( + data, + ); + } + + late final _spine_skeleton_data_get_num_eventsPtr = + _lookup>( + 'spine_skeleton_data_get_num_events'); + late final _spine_skeleton_data_get_num_events = + _spine_skeleton_data_get_num_eventsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_events( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_events( + data, + ); + } + + late final _spine_skeleton_data_get_eventsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>('spine_skeleton_data_get_events'); + late final _spine_skeleton_data_get_events = + _spine_skeleton_data_get_eventsPtr.asFunction< + ffi.Pointer Function(spine_skeleton_data)>(); + + int spine_skeleton_data_get_num_animations( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_animations( + data, + ); + } + + late final _spine_skeleton_data_get_num_animationsPtr = + _lookup>( + 'spine_skeleton_data_get_num_animations'); + late final _spine_skeleton_data_get_num_animations = + _spine_skeleton_data_get_num_animationsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_animations( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_animations( + data, + ); + } + + late final _spine_skeleton_data_get_animationsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>('spine_skeleton_data_get_animations'); + late final _spine_skeleton_data_get_animations = + _spine_skeleton_data_get_animationsPtr.asFunction< + ffi.Pointer Function(spine_skeleton_data)>(); + + int spine_skeleton_data_get_num_ik_constraints( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_ik_constraints( + data, + ); + } + + late final _spine_skeleton_data_get_num_ik_constraintsPtr = + _lookup>( + 'spine_skeleton_data_get_num_ik_constraints'); + late final _spine_skeleton_data_get_num_ik_constraints = + _spine_skeleton_data_get_num_ik_constraintsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_ik_constraints( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_ik_constraints( + data, + ); + } + + late final _spine_skeleton_data_get_ik_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>('spine_skeleton_data_get_ik_constraints'); + late final _spine_skeleton_data_get_ik_constraints = + _spine_skeleton_data_get_ik_constraintsPtr.asFunction< + ffi.Pointer Function( + spine_skeleton_data)>(); + + int spine_skeleton_data_get_num_transform_constraints( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_transform_constraints( + data, + ); + } + + late final _spine_skeleton_data_get_num_transform_constraintsPtr = + _lookup>( + 'spine_skeleton_data_get_num_transform_constraints'); + late final _spine_skeleton_data_get_num_transform_constraints = + _spine_skeleton_data_get_num_transform_constraintsPtr + .asFunction(); + + ffi.Pointer + spine_skeleton_data_get_transform_constraints( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_transform_constraints( + data, + ); + } + + late final _spine_skeleton_data_get_transform_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>( + 'spine_skeleton_data_get_transform_constraints'); + late final _spine_skeleton_data_get_transform_constraints = + _spine_skeleton_data_get_transform_constraintsPtr.asFunction< + ffi.Pointer Function( + spine_skeleton_data)>(); + + int spine_skeleton_data_get_num_path_constraints( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_num_path_constraints( + data, + ); + } + + late final _spine_skeleton_data_get_num_path_constraintsPtr = + _lookup>( + 'spine_skeleton_data_get_num_path_constraints'); + late final _spine_skeleton_data_get_num_path_constraints = + _spine_skeleton_data_get_num_path_constraintsPtr + .asFunction(); + + ffi.Pointer + spine_skeleton_data_get_path_constraints( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_path_constraints( + data, + ); + } + + late final _spine_skeleton_data_get_path_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton_data)>>( + 'spine_skeleton_data_get_path_constraints'); + late final _spine_skeleton_data_get_path_constraints = + _spine_skeleton_data_get_path_constraintsPtr.asFunction< + ffi.Pointer Function( + spine_skeleton_data)>(); + + double spine_skeleton_data_get_x( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_x( + data, + ); + } + + late final _spine_skeleton_data_get_xPtr = + _lookup>( + 'spine_skeleton_data_get_x'); + late final _spine_skeleton_data_get_x = _spine_skeleton_data_get_xPtr + .asFunction(); + + void spine_skeleton_data_set_x( + spine_skeleton_data data, + double x, + ) { + return _spine_skeleton_data_set_x( + data, + x, + ); + } + + late final _spine_skeleton_data_set_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_skeleton_data, ffi.Float)>>('spine_skeleton_data_set_x'); + late final _spine_skeleton_data_set_x = _spine_skeleton_data_set_xPtr + .asFunction(); + + double spine_skeleton_data_get_y( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_y( + data, + ); + } + + late final _spine_skeleton_data_get_yPtr = + _lookup>( + 'spine_skeleton_data_get_y'); + late final _spine_skeleton_data_get_y = _spine_skeleton_data_get_yPtr + .asFunction(); + + void spine_skeleton_data_set_y( + spine_skeleton_data data, + double y, + ) { + return _spine_skeleton_data_set_y( + data, + y, + ); + } + + late final _spine_skeleton_data_set_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_skeleton_data, ffi.Float)>>('spine_skeleton_data_set_y'); + late final _spine_skeleton_data_set_y = _spine_skeleton_data_set_yPtr + .asFunction(); + + double spine_skeleton_data_get_width( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_width( + data, + ); + } + + late final _spine_skeleton_data_get_widthPtr = + _lookup>( + 'spine_skeleton_data_get_width'); + late final _spine_skeleton_data_get_width = _spine_skeleton_data_get_widthPtr + .asFunction(); + + void spine_skeleton_data_set_width( + spine_skeleton_data data, + double width, + ) { + return _spine_skeleton_data_set_width( + data, + width, + ); + } + + late final _spine_skeleton_data_set_widthPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton_data, + ffi.Float)>>('spine_skeleton_data_set_width'); + late final _spine_skeleton_data_set_width = _spine_skeleton_data_set_widthPtr + .asFunction(); + + double spine_skeleton_data_get_height( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_height( + data, + ); + } + + late final _spine_skeleton_data_get_heightPtr = + _lookup>( + 'spine_skeleton_data_get_height'); + late final _spine_skeleton_data_get_height = + _spine_skeleton_data_get_heightPtr + .asFunction(); + + void spine_skeleton_data_set_height( + spine_skeleton_data data, + double height, + ) { + return _spine_skeleton_data_set_height( + data, + height, + ); + } + + late final _spine_skeleton_data_set_heightPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton_data, + ffi.Float)>>('spine_skeleton_data_set_height'); + late final _spine_skeleton_data_set_height = + _spine_skeleton_data_set_heightPtr + .asFunction(); + + ffi.Pointer spine_skeleton_data_get_version( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_version( + data, + ); + } + + late final _spine_skeleton_data_get_versionPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton_data)>>( + 'spine_skeleton_data_get_version'); + late final _spine_skeleton_data_get_version = + _spine_skeleton_data_get_versionPtr + .asFunction Function(spine_skeleton_data)>(); + + /// OMITTED setVersion() + ffi.Pointer spine_skeleton_data_get_hash( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_hash( + data, + ); + } + + late final _spine_skeleton_data_get_hashPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton_data)>>( + 'spine_skeleton_data_get_hash'); + late final _spine_skeleton_data_get_hash = _spine_skeleton_data_get_hashPtr + .asFunction Function(spine_skeleton_data)>(); + + /// OMITTED setHash() + ffi.Pointer spine_skeleton_data_get_images_path( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_images_path( + data, + ); + } + + late final _spine_skeleton_data_get_images_pathPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton_data)>>( + 'spine_skeleton_data_get_images_path'); + late final _spine_skeleton_data_get_images_path = + _spine_skeleton_data_get_images_pathPtr + .asFunction Function(spine_skeleton_data)>(); + + /// OMITTED setImagesPath() + ffi.Pointer spine_skeleton_data_get_audio_path( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_audio_path( + data, + ); + } + + late final _spine_skeleton_data_get_audio_pathPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton_data)>>( + 'spine_skeleton_data_get_audio_path'); + late final _spine_skeleton_data_get_audio_path = + _spine_skeleton_data_get_audio_pathPtr + .asFunction Function(spine_skeleton_data)>(); + + /// OMITTED setAudioPath() + double spine_skeleton_data_get_fps( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_get_fps( + data, + ); + } + + late final _spine_skeleton_data_get_fpsPtr = + _lookup>( + 'spine_skeleton_data_get_fps'); + late final _spine_skeleton_data_get_fps = _spine_skeleton_data_get_fpsPtr + .asFunction(); + + /// OMITTED setFps() + void spine_skeleton_data_dispose( + spine_skeleton_data data, + ) { + return _spine_skeleton_data_dispose( + data, + ); + } + + late final _spine_skeleton_data_disposePtr = + _lookup>( + 'spine_skeleton_data_dispose'); + late final _spine_skeleton_data_dispose = _spine_skeleton_data_disposePtr + .asFunction(); + + spine_skeleton_drawable spine_skeleton_drawable_create( + spine_skeleton_data skeletonData, + ) { + return _spine_skeleton_drawable_create( + skeletonData, + ); + } + + late final _spine_skeleton_drawable_createPtr = _lookup< + ffi.NativeFunction< + spine_skeleton_drawable Function( + spine_skeleton_data)>>('spine_skeleton_drawable_create'); + late final _spine_skeleton_drawable_create = + _spine_skeleton_drawable_createPtr + .asFunction(); + + spine_render_command spine_skeleton_drawable_render( + spine_skeleton_drawable drawable, + ) { + return _spine_skeleton_drawable_render( + drawable, + ); + } + + late final _spine_skeleton_drawable_renderPtr = _lookup< + ffi.NativeFunction< + spine_render_command Function( + spine_skeleton_drawable)>>('spine_skeleton_drawable_render'); + late final _spine_skeleton_drawable_render = + _spine_skeleton_drawable_renderPtr + .asFunction(); + + void spine_skeleton_drawable_dispose( + spine_skeleton_drawable drawable, + ) { + return _spine_skeleton_drawable_dispose( + drawable, + ); + } + + late final _spine_skeleton_drawable_disposePtr = + _lookup>( + 'spine_skeleton_drawable_dispose'); + late final _spine_skeleton_drawable_dispose = + _spine_skeleton_drawable_disposePtr + .asFunction(); + + spine_skeleton spine_skeleton_drawable_get_skeleton( + spine_skeleton_drawable drawable, + ) { + return _spine_skeleton_drawable_get_skeleton( + drawable, + ); + } + + late final _spine_skeleton_drawable_get_skeletonPtr = _lookup< + ffi.NativeFunction>( + 'spine_skeleton_drawable_get_skeleton'); + late final _spine_skeleton_drawable_get_skeleton = + _spine_skeleton_drawable_get_skeletonPtr + .asFunction(); + + spine_animation_state spine_skeleton_drawable_get_animation_state( + spine_skeleton_drawable drawable, + ) { + return _spine_skeleton_drawable_get_animation_state( + drawable, + ); + } + + late final _spine_skeleton_drawable_get_animation_statePtr = _lookup< + ffi.NativeFunction< + spine_animation_state Function(spine_skeleton_drawable)>>( + 'spine_skeleton_drawable_get_animation_state'); + late final _spine_skeleton_drawable_get_animation_state = + _spine_skeleton_drawable_get_animation_statePtr.asFunction< + spine_animation_state Function(spine_skeleton_drawable)>(); + + spine_animation_state_data spine_skeleton_drawable_get_animation_state_data( + spine_skeleton_drawable drawable, + ) { + return _spine_skeleton_drawable_get_animation_state_data( + drawable, + ); + } + + late final _spine_skeleton_drawable_get_animation_state_dataPtr = _lookup< + ffi.NativeFunction< + spine_animation_state_data Function(spine_skeleton_drawable)>>( + 'spine_skeleton_drawable_get_animation_state_data'); + late final _spine_skeleton_drawable_get_animation_state_data = + _spine_skeleton_drawable_get_animation_state_dataPtr.asFunction< + spine_animation_state_data Function(spine_skeleton_drawable)>(); + + spine_animation_state_events + spine_skeleton_drawable_get_animation_state_events( + spine_skeleton_drawable drawable, + ) { + return _spine_skeleton_drawable_get_animation_state_events( + drawable, + ); + } + + late final _spine_skeleton_drawable_get_animation_state_eventsPtr = _lookup< + ffi.NativeFunction< + spine_animation_state_events Function(spine_skeleton_drawable)>>( + 'spine_skeleton_drawable_get_animation_state_events'); + late final _spine_skeleton_drawable_get_animation_state_events = + _spine_skeleton_drawable_get_animation_state_eventsPtr.asFunction< + spine_animation_state_events Function(spine_skeleton_drawable)>(); + + ffi.Pointer spine_render_command_get_positions( + spine_render_command command, + ) { + return _spine_render_command_get_positions( + command, + ); + } + + late final _spine_render_command_get_positionsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_render_command)>>('spine_render_command_get_positions'); + late final _spine_render_command_get_positions = + _spine_render_command_get_positionsPtr + .asFunction Function(spine_render_command)>(); + + ffi.Pointer spine_render_command_get_uvs( + spine_render_command command, + ) { + return _spine_render_command_get_uvs( + command, + ); + } + + late final _spine_render_command_get_uvsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_render_command)>>('spine_render_command_get_uvs'); + late final _spine_render_command_get_uvs = _spine_render_command_get_uvsPtr + .asFunction Function(spine_render_command)>(); + + ffi.Pointer spine_render_command_get_colors( + spine_render_command command, + ) { + return _spine_render_command_get_colors( + command, + ); + } + + late final _spine_render_command_get_colorsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_render_command)>>('spine_render_command_get_colors'); + late final _spine_render_command_get_colors = + _spine_render_command_get_colorsPtr + .asFunction Function(spine_render_command)>(); + + int spine_render_command_get_num_vertices( + spine_render_command command, + ) { + return _spine_render_command_get_num_vertices( + command, + ); + } + + late final _spine_render_command_get_num_verticesPtr = + _lookup>( + 'spine_render_command_get_num_vertices'); + late final _spine_render_command_get_num_vertices = + _spine_render_command_get_num_verticesPtr + .asFunction(); + + ffi.Pointer spine_render_command_get_indices( + spine_render_command command, + ) { + return _spine_render_command_get_indices( + command, + ); + } + + late final _spine_render_command_get_indicesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_render_command)>>('spine_render_command_get_indices'); + late final _spine_render_command_get_indices = + _spine_render_command_get_indicesPtr + .asFunction Function(spine_render_command)>(); + + int spine_render_command_get_num_indices( + spine_render_command command, + ) { + return _spine_render_command_get_num_indices( + command, + ); + } + + late final _spine_render_command_get_num_indicesPtr = + _lookup>( + 'spine_render_command_get_num_indices'); + late final _spine_render_command_get_num_indices = + _spine_render_command_get_num_indicesPtr + .asFunction(); + + int spine_render_command_get_atlas_page( + spine_render_command command, + ) { + return _spine_render_command_get_atlas_page( + command, + ); + } + + late final _spine_render_command_get_atlas_pagePtr = + _lookup>( + 'spine_render_command_get_atlas_page'); + late final _spine_render_command_get_atlas_page = + _spine_render_command_get_atlas_pagePtr + .asFunction(); + + int spine_render_command_get_blend_mode( + spine_render_command command, + ) { + return _spine_render_command_get_blend_mode( + command, + ); + } + + late final _spine_render_command_get_blend_modePtr = + _lookup>( + 'spine_render_command_get_blend_mode'); + late final _spine_render_command_get_blend_mode = + _spine_render_command_get_blend_modePtr + .asFunction(); + + spine_render_command spine_render_command_get_next( + spine_render_command command, + ) { + return _spine_render_command_get_next( + command, + ); + } + + late final _spine_render_command_get_nextPtr = _lookup< + ffi.NativeFunction< + spine_render_command Function( + spine_render_command)>>('spine_render_command_get_next'); + late final _spine_render_command_get_next = _spine_render_command_get_nextPtr + .asFunction(); + + ffi.Pointer spine_animation_get_name( + spine_animation animation, + ) { + return _spine_animation_get_name( + animation, + ); + } + + late final _spine_animation_get_namePtr = + _lookup Function(spine_animation)>>( + 'spine_animation_get_name'); + late final _spine_animation_get_name = _spine_animation_get_namePtr + .asFunction Function(spine_animation)>(); + + /// OMITTED getTimelines() + /// OMITTED hasTimeline() + double spine_animation_get_duration( + spine_animation animation, + ) { + return _spine_animation_get_duration( + animation, + ); + } + + late final _spine_animation_get_durationPtr = + _lookup>( + 'spine_animation_get_duration'); + late final _spine_animation_get_duration = _spine_animation_get_durationPtr + .asFunction(); + + /// OMITTED setDuration() + spine_skeleton_data spine_animation_state_data_get_skeleton_data( + spine_animation_state_data stateData, + ) { + return _spine_animation_state_data_get_skeleton_data( + stateData, + ); + } + + late final _spine_animation_state_data_get_skeleton_dataPtr = _lookup< + ffi.NativeFunction< + spine_skeleton_data Function(spine_animation_state_data)>>( + 'spine_animation_state_data_get_skeleton_data'); + late final _spine_animation_state_data_get_skeleton_data = + _spine_animation_state_data_get_skeleton_dataPtr.asFunction< + spine_skeleton_data Function(spine_animation_state_data)>(); + + double spine_animation_state_data_get_default_mix( + spine_animation_state_data stateData, + ) { + return _spine_animation_state_data_get_default_mix( + stateData, + ); + } + + late final _spine_animation_state_data_get_default_mixPtr = _lookup< + ffi.NativeFunction>( + 'spine_animation_state_data_get_default_mix'); + late final _spine_animation_state_data_get_default_mix = + _spine_animation_state_data_get_default_mixPtr + .asFunction(); + + void spine_animation_state_data_set_default_mix( + spine_animation_state_data stateData, + double defaultMix, + ) { + return _spine_animation_state_data_set_default_mix( + stateData, + defaultMix, + ); + } + + late final _spine_animation_state_data_set_default_mixPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state_data, + ffi.Float)>>('spine_animation_state_data_set_default_mix'); + late final _spine_animation_state_data_set_default_mix = + _spine_animation_state_data_set_default_mixPtr + .asFunction(); + + void spine_animation_state_data_set_mix( + spine_animation_state_data stateData, + spine_animation from, + spine_animation to, + double duration, + ) { + return _spine_animation_state_data_set_mix( + stateData, + from, + to, + duration, + ); + } + + late final _spine_animation_state_data_set_mixPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_animation_state_data, + spine_animation, + spine_animation, + ffi.Float)>>('spine_animation_state_data_set_mix'); + late final _spine_animation_state_data_set_mix = + _spine_animation_state_data_set_mixPtr.asFunction< + void Function(spine_animation_state_data, spine_animation, + spine_animation, double)>(); + + double spine_animation_state_data_get_mix( + spine_animation_state_data stateData, + spine_animation from, + spine_animation to, + ) { + return _spine_animation_state_data_get_mix( + stateData, + from, + to, + ); + } + + late final _spine_animation_state_data_get_mixPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_animation_state_data, spine_animation, + spine_animation)>>('spine_animation_state_data_get_mix'); + late final _spine_animation_state_data_get_mix = + _spine_animation_state_data_get_mixPtr.asFunction< + double Function( + spine_animation_state_data, spine_animation, spine_animation)>(); + + void spine_animation_state_data_set_mix_by_name( + spine_animation_state_data stateData, + ffi.Pointer fromName, + ffi.Pointer toName, + double duration, + ) { + return _spine_animation_state_data_set_mix_by_name( + stateData, + fromName, + toName, + duration, + ); + } + + late final _spine_animation_state_data_set_mix_by_namePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_animation_state_data, + ffi.Pointer, + ffi.Pointer, + ffi.Float)>>('spine_animation_state_data_set_mix_by_name'); + late final _spine_animation_state_data_set_mix_by_name = + _spine_animation_state_data_set_mix_by_namePtr.asFunction< + void Function(spine_animation_state_data, ffi.Pointer, + ffi.Pointer, double)>(); + + double spine_animation_state_data_get_mix_by_name( + spine_animation_state_data stateData, + ffi.Pointer fromName, + ffi.Pointer toName, + ) { + return _spine_animation_state_data_get_mix_by_name( + stateData, + fromName, + toName, + ); + } + + late final _spine_animation_state_data_get_mix_by_namePtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_animation_state_data, ffi.Pointer, + ffi.Pointer)>>( + 'spine_animation_state_data_get_mix_by_name'); + late final _spine_animation_state_data_get_mix_by_name = + _spine_animation_state_data_get_mix_by_namePtr.asFunction< + double Function(spine_animation_state_data, ffi.Pointer, + ffi.Pointer)>(); + + void spine_animation_state_data_clear( + spine_animation_state_data stateData, + ) { + return _spine_animation_state_data_clear( + stateData, + ); + } + + late final _spine_animation_state_data_clearPtr = _lookup< + ffi.NativeFunction>( + 'spine_animation_state_data_clear'); + late final _spine_animation_state_data_clear = + _spine_animation_state_data_clearPtr + .asFunction(); + + void spine_animation_state_update( + spine_animation_state state, + double delta, + ) { + return _spine_animation_state_update( + state, + delta, + ); + } + + late final _spine_animation_state_updatePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state, + ffi.Float)>>('spine_animation_state_update'); + late final _spine_animation_state_update = _spine_animation_state_updatePtr + .asFunction(); + + void spine_animation_state_apply( + spine_animation_state state, + spine_skeleton skeleton, + ) { + return _spine_animation_state_apply( + state, + skeleton, + ); + } + + late final _spine_animation_state_applyPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state, + spine_skeleton)>>('spine_animation_state_apply'); + late final _spine_animation_state_apply = _spine_animation_state_applyPtr + .asFunction(); + + void spine_animation_state_clear_tracks( + spine_animation_state state, + ) { + return _spine_animation_state_clear_tracks( + state, + ); + } + + late final _spine_animation_state_clear_tracksPtr = + _lookup>( + 'spine_animation_state_clear_tracks'); + late final _spine_animation_state_clear_tracks = + _spine_animation_state_clear_tracksPtr + .asFunction(); + + void spine_animation_state_clear_track( + spine_animation_state state, + int trackIndex, + ) { + return _spine_animation_state_clear_track( + state, + trackIndex, + ); + } + + late final _spine_animation_state_clear_trackPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state, + ffi.Int32)>>('spine_animation_state_clear_track'); + late final _spine_animation_state_clear_track = + _spine_animation_state_clear_trackPtr + .asFunction(); + + int spine_animation_state_get_num_tracks( + spine_animation_state state, + ) { + return _spine_animation_state_get_num_tracks( + state, + ); + } + + late final _spine_animation_state_get_num_tracksPtr = + _lookup>( + 'spine_animation_state_get_num_tracks'); + late final _spine_animation_state_get_num_tracks = + _spine_animation_state_get_num_tracksPtr + .asFunction(); + + spine_track_entry spine_animation_state_set_animation_by_name( + spine_animation_state state, + int trackIndex, + ffi.Pointer animationName, + int loop, + ) { + return _spine_animation_state_set_animation_by_name( + state, + trackIndex, + animationName, + loop, + ); + } + + late final _spine_animation_state_set_animation_by_namePtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function( + spine_animation_state, + ffi.Int32, + ffi.Pointer, + ffi.Int32)>>('spine_animation_state_set_animation_by_name'); + late final _spine_animation_state_set_animation_by_name = + _spine_animation_state_set_animation_by_namePtr.asFunction< + spine_track_entry Function( + spine_animation_state, int, ffi.Pointer, int)>(); + + spine_track_entry spine_animation_state_set_animation( + spine_animation_state state, + int trackIndex, + spine_animation animation, + int loop, + ) { + return _spine_animation_state_set_animation( + state, + trackIndex, + animation, + loop, + ); + } + + late final _spine_animation_state_set_animationPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function( + spine_animation_state, + ffi.Int32, + spine_animation, + ffi.Int32)>>('spine_animation_state_set_animation'); + late final _spine_animation_state_set_animation = + _spine_animation_state_set_animationPtr.asFunction< + spine_track_entry Function( + spine_animation_state, int, spine_animation, int)>(); + + spine_track_entry spine_animation_state_add_animation_by_name( + spine_animation_state state, + int trackIndex, + ffi.Pointer animationName, + int loop, + double delay, + ) { + return _spine_animation_state_add_animation_by_name( + state, + trackIndex, + animationName, + loop, + delay, + ); + } + + late final _spine_animation_state_add_animation_by_namePtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function( + spine_animation_state, + ffi.Int32, + ffi.Pointer, + ffi.Int32, + ffi.Float)>>('spine_animation_state_add_animation_by_name'); + late final _spine_animation_state_add_animation_by_name = + _spine_animation_state_add_animation_by_namePtr.asFunction< + spine_track_entry Function( + spine_animation_state, int, ffi.Pointer, int, double)>(); + + spine_track_entry spine_animation_state_add_animation( + spine_animation_state state, + int trackIndex, + spine_animation animation, + int loop, + double delay, + ) { + return _spine_animation_state_add_animation( + state, + trackIndex, + animation, + loop, + delay, + ); + } + + late final _spine_animation_state_add_animationPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function( + spine_animation_state, + ffi.Int32, + spine_animation, + ffi.Int32, + ffi.Float)>>('spine_animation_state_add_animation'); + late final _spine_animation_state_add_animation = + _spine_animation_state_add_animationPtr.asFunction< + spine_track_entry Function( + spine_animation_state, int, spine_animation, int, double)>(); + + spine_track_entry spine_animation_state_set_empty_animation( + spine_animation_state state, + int trackIndex, + double mixDuration, + ) { + return _spine_animation_state_set_empty_animation( + state, + trackIndex, + mixDuration, + ); + } + + late final _spine_animation_state_set_empty_animationPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function(spine_animation_state, ffi.Int32, + ffi.Float)>>('spine_animation_state_set_empty_animation'); + late final _spine_animation_state_set_empty_animation = + _spine_animation_state_set_empty_animationPtr.asFunction< + spine_track_entry Function(spine_animation_state, int, double)>(); + + spine_track_entry spine_animation_state_add_empty_animation( + spine_animation_state state, + int trackIndex, + double mixDuration, + double delay, + ) { + return _spine_animation_state_add_empty_animation( + state, + trackIndex, + mixDuration, + delay, + ); + } + + late final _spine_animation_state_add_empty_animationPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function( + spine_animation_state, + ffi.Int32, + ffi.Float, + ffi.Float)>>('spine_animation_state_add_empty_animation'); + late final _spine_animation_state_add_empty_animation = + _spine_animation_state_add_empty_animationPtr.asFunction< + spine_track_entry Function( + spine_animation_state, int, double, double)>(); + + void spine_animation_state_set_empty_animations( + spine_animation_state state, + double mixDuration, + ) { + return _spine_animation_state_set_empty_animations( + state, + mixDuration, + ); + } + + late final _spine_animation_state_set_empty_animationsPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state, + ffi.Float)>>('spine_animation_state_set_empty_animations'); + late final _spine_animation_state_set_empty_animations = + _spine_animation_state_set_empty_animationsPtr + .asFunction(); + + spine_track_entry spine_animation_state_get_current( + spine_animation_state state, + int trackIndex, + ) { + return _spine_animation_state_get_current( + state, + trackIndex, + ); + } + + late final _spine_animation_state_get_currentPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function(spine_animation_state, + ffi.Int32)>>('spine_animation_state_get_current'); + late final _spine_animation_state_get_current = + _spine_animation_state_get_currentPtr + .asFunction(); + + spine_animation_state_data spine_animation_state_get_data( + spine_animation_state state, + ) { + return _spine_animation_state_get_data( + state, + ); + } + + late final _spine_animation_state_get_dataPtr = _lookup< + ffi.NativeFunction< + spine_animation_state_data Function( + spine_animation_state)>>('spine_animation_state_get_data'); + late final _spine_animation_state_get_data = + _spine_animation_state_get_dataPtr.asFunction< + spine_animation_state_data Function(spine_animation_state)>(); + + double spine_animation_state_get_time_scale( + spine_animation_state state, + ) { + return _spine_animation_state_get_time_scale( + state, + ); + } + + late final _spine_animation_state_get_time_scalePtr = + _lookup>( + 'spine_animation_state_get_time_scale'); + late final _spine_animation_state_get_time_scale = + _spine_animation_state_get_time_scalePtr + .asFunction(); + + void spine_animation_state_set_time_scale( + spine_animation_state state, + double timeScale, + ) { + return _spine_animation_state_set_time_scale( + state, + timeScale, + ); + } + + late final _spine_animation_state_set_time_scalePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state, + ffi.Float)>>('spine_animation_state_set_time_scale'); + late final _spine_animation_state_set_time_scale = + _spine_animation_state_set_time_scalePtr + .asFunction(); + + /// OMITTED setListener() + /// OMITTED setListener() + /// OMITTED disableQueue() + /// OMITTED enableQueue() + /// OMITTED setManualTrackEntryDisposal() + /// OMITTED getManualTrackEntryDisposal() + void spine_animation_state_dispose_track_entry( + spine_animation_state state, + spine_track_entry entry, + ) { + return _spine_animation_state_dispose_track_entry( + state, + entry, + ); + } + + late final _spine_animation_state_dispose_track_entryPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_animation_state, + spine_track_entry)>>('spine_animation_state_dispose_track_entry'); + late final _spine_animation_state_dispose_track_entry = + _spine_animation_state_dispose_track_entryPtr.asFunction< + void Function(spine_animation_state, spine_track_entry)>(); + + int spine_animation_state_events_get_num_events( + spine_animation_state_events events, + ) { + return _spine_animation_state_events_get_num_events( + events, + ); + } + + late final _spine_animation_state_events_get_num_eventsPtr = _lookup< + ffi.NativeFunction>( + 'spine_animation_state_events_get_num_events'); + late final _spine_animation_state_events_get_num_events = + _spine_animation_state_events_get_num_eventsPtr + .asFunction(); + + int spine_animation_state_events_get_event_type( + spine_animation_state_events events, + int index, + ) { + return _spine_animation_state_events_get_event_type( + events, + index, + ); + } + + late final _spine_animation_state_events_get_event_typePtr = _lookup< + ffi.NativeFunction< + ffi.Int32 Function(spine_animation_state_events, + ffi.Int32)>>('spine_animation_state_events_get_event_type'); + late final _spine_animation_state_events_get_event_type = + _spine_animation_state_events_get_event_typePtr + .asFunction(); + + spine_track_entry spine_animation_state_events_get_track_entry( + spine_animation_state_events events, + int index, + ) { + return _spine_animation_state_events_get_track_entry( + events, + index, + ); + } + + late final _spine_animation_state_events_get_track_entryPtr = _lookup< + ffi.NativeFunction< + spine_track_entry Function(spine_animation_state_events, + ffi.Int32)>>('spine_animation_state_events_get_track_entry'); + late final _spine_animation_state_events_get_track_entry = + _spine_animation_state_events_get_track_entryPtr.asFunction< + spine_track_entry Function(spine_animation_state_events, int)>(); + + spine_event spine_animation_state_events_get_event( + spine_animation_state_events events, + int index, + ) { + return _spine_animation_state_events_get_event( + events, + index, + ); + } + + late final _spine_animation_state_events_get_eventPtr = _lookup< + ffi.NativeFunction< + spine_event Function(spine_animation_state_events, + ffi.Int32)>>('spine_animation_state_events_get_event'); + late final _spine_animation_state_events_get_event = + _spine_animation_state_events_get_eventPtr.asFunction< + spine_event Function(spine_animation_state_events, int)>(); + + void spine_animation_state_events_reset( + spine_animation_state_events events, + ) { + return _spine_animation_state_events_reset( + events, + ); + } + + late final _spine_animation_state_events_resetPtr = _lookup< + ffi.NativeFunction>( + 'spine_animation_state_events_reset'); + late final _spine_animation_state_events_reset = + _spine_animation_state_events_resetPtr + .asFunction(); + + int spine_track_entry_get_track_index( + spine_track_entry entry, + ) { + return _spine_track_entry_get_track_index( + entry, + ); + } + + late final _spine_track_entry_get_track_indexPtr = + _lookup>( + 'spine_track_entry_get_track_index'); + late final _spine_track_entry_get_track_index = + _spine_track_entry_get_track_indexPtr + .asFunction(); + + spine_animation spine_track_entry_get_animation( + spine_track_entry entry, + ) { + return _spine_track_entry_get_animation( + entry, + ); + } + + late final _spine_track_entry_get_animationPtr = + _lookup>( + 'spine_track_entry_get_animation'); + late final _spine_track_entry_get_animation = + _spine_track_entry_get_animationPtr + .asFunction(); + + spine_track_entry spine_track_entry_get_previous( + spine_track_entry entry, + ) { + return _spine_track_entry_get_previous( + entry, + ); + } + + late final _spine_track_entry_get_previousPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_get_previous'); + late final _spine_track_entry_get_previous = + _spine_track_entry_get_previousPtr + .asFunction(); + + int spine_track_entry_get_loop( + spine_track_entry entry, + ) { + return _spine_track_entry_get_loop( + entry, + ); + } + + late final _spine_track_entry_get_loopPtr = + _lookup>( + 'spine_track_entry_get_loop'); + late final _spine_track_entry_get_loop = _spine_track_entry_get_loopPtr + .asFunction(); + + void spine_track_entry_set_loop( + spine_track_entry entry, + int loop, + ) { + return _spine_track_entry_set_loop( + entry, + loop, + ); + } + + late final _spine_track_entry_set_loopPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_loop'); + late final _spine_track_entry_set_loop = _spine_track_entry_set_loopPtr + .asFunction(); + + int spine_track_entry_get_hold_previous( + spine_track_entry entry, + ) { + return _spine_track_entry_get_hold_previous( + entry, + ); + } + + late final _spine_track_entry_get_hold_previousPtr = + _lookup>( + 'spine_track_entry_get_hold_previous'); + late final _spine_track_entry_get_hold_previous = + _spine_track_entry_get_hold_previousPtr + .asFunction(); + + void spine_track_entry_set_hold_previous( + spine_track_entry entry, + int holdPrevious, + ) { + return _spine_track_entry_set_hold_previous( + entry, + holdPrevious, + ); + } + + late final _spine_track_entry_set_hold_previousPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_hold_previous'); + late final _spine_track_entry_set_hold_previous = + _spine_track_entry_set_hold_previousPtr + .asFunction(); + + int spine_track_entry_get_reverse( + spine_track_entry entry, + ) { + return _spine_track_entry_get_reverse( + entry, + ); + } + + late final _spine_track_entry_get_reversePtr = + _lookup>( + 'spine_track_entry_get_reverse'); + late final _spine_track_entry_get_reverse = _spine_track_entry_get_reversePtr + .asFunction(); + + void spine_track_entry_set_reverse( + spine_track_entry entry, + int reverse, + ) { + return _spine_track_entry_set_reverse( + entry, + reverse, + ); + } + + late final _spine_track_entry_set_reversePtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_reverse'); + late final _spine_track_entry_set_reverse = _spine_track_entry_set_reversePtr + .asFunction(); + + int spine_track_entry_get_shortest_rotation( + spine_track_entry entry, + ) { + return _spine_track_entry_get_shortest_rotation( + entry, + ); + } + + late final _spine_track_entry_get_shortest_rotationPtr = + _lookup>( + 'spine_track_entry_get_shortest_rotation'); + late final _spine_track_entry_get_shortest_rotation = + _spine_track_entry_get_shortest_rotationPtr + .asFunction(); + + void spine_track_entry_set_shortest_rotation( + spine_track_entry entry, + int shortestRotation, + ) { + return _spine_track_entry_set_shortest_rotation( + entry, + shortestRotation, + ); + } + + late final _spine_track_entry_set_shortest_rotationPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_shortest_rotation'); + late final _spine_track_entry_set_shortest_rotation = + _spine_track_entry_set_shortest_rotationPtr + .asFunction(); + + double spine_track_entry_get_delay( + spine_track_entry entry, + ) { + return _spine_track_entry_get_delay( + entry, + ); + } + + late final _spine_track_entry_get_delayPtr = + _lookup>( + 'spine_track_entry_get_delay'); + late final _spine_track_entry_get_delay = _spine_track_entry_get_delayPtr + .asFunction(); + + void spine_track_entry_set_delay( + spine_track_entry entry, + double delay, + ) { + return _spine_track_entry_set_delay( + entry, + delay, + ); + } + + late final _spine_track_entry_set_delayPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_delay'); + late final _spine_track_entry_set_delay = _spine_track_entry_set_delayPtr + .asFunction(); + + double spine_track_entry_get_track_time( + spine_track_entry entry, + ) { + return _spine_track_entry_get_track_time( + entry, + ); + } + + late final _spine_track_entry_get_track_timePtr = + _lookup>( + 'spine_track_entry_get_track_time'); + late final _spine_track_entry_get_track_time = + _spine_track_entry_get_track_timePtr + .asFunction(); + + void spine_track_entry_set_track_time( + spine_track_entry entry, + double trackTime, + ) { + return _spine_track_entry_set_track_time( + entry, + trackTime, + ); + } + + late final _spine_track_entry_set_track_timePtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_track_time'); + late final _spine_track_entry_set_track_time = + _spine_track_entry_set_track_timePtr + .asFunction(); + + double spine_track_entry_get_track_end( + spine_track_entry entry, + ) { + return _spine_track_entry_get_track_end( + entry, + ); + } + + late final _spine_track_entry_get_track_endPtr = + _lookup>( + 'spine_track_entry_get_track_end'); + late final _spine_track_entry_get_track_end = + _spine_track_entry_get_track_endPtr + .asFunction(); + + void spine_track_entry_set_track_end( + spine_track_entry entry, + double trackEnd, + ) { + return _spine_track_entry_set_track_end( + entry, + trackEnd, + ); + } + + late final _spine_track_entry_set_track_endPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_track_end'); + late final _spine_track_entry_set_track_end = + _spine_track_entry_set_track_endPtr + .asFunction(); + + double spine_track_entry_get_animation_start( + spine_track_entry entry, + ) { + return _spine_track_entry_get_animation_start( + entry, + ); + } + + late final _spine_track_entry_get_animation_startPtr = + _lookup>( + 'spine_track_entry_get_animation_start'); + late final _spine_track_entry_get_animation_start = + _spine_track_entry_get_animation_startPtr + .asFunction(); + + void spine_track_entry_set_animation_start( + spine_track_entry entry, + double animationStart, + ) { + return _spine_track_entry_set_animation_start( + entry, + animationStart, + ); + } + + late final _spine_track_entry_set_animation_startPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_animation_start'); + late final _spine_track_entry_set_animation_start = + _spine_track_entry_set_animation_startPtr + .asFunction(); + + double spine_track_entry_get_animation_end( + spine_track_entry entry, + ) { + return _spine_track_entry_get_animation_end( + entry, + ); + } + + late final _spine_track_entry_get_animation_endPtr = + _lookup>( + 'spine_track_entry_get_animation_end'); + late final _spine_track_entry_get_animation_end = + _spine_track_entry_get_animation_endPtr + .asFunction(); + + void spine_track_entry_set_animation_end( + spine_track_entry entry, + double animationEnd, + ) { + return _spine_track_entry_set_animation_end( + entry, + animationEnd, + ); + } + + late final _spine_track_entry_set_animation_endPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_animation_end'); + late final _spine_track_entry_set_animation_end = + _spine_track_entry_set_animation_endPtr + .asFunction(); + + double spine_track_entry_get_animation_last( + spine_track_entry entry, + ) { + return _spine_track_entry_get_animation_last( + entry, + ); + } + + late final _spine_track_entry_get_animation_lastPtr = + _lookup>( + 'spine_track_entry_get_animation_last'); + late final _spine_track_entry_get_animation_last = + _spine_track_entry_get_animation_lastPtr + .asFunction(); + + void spine_track_entry_set_animation_last( + spine_track_entry entry, + double animationLast, + ) { + return _spine_track_entry_set_animation_last( + entry, + animationLast, + ); + } + + late final _spine_track_entry_set_animation_lastPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_animation_last'); + late final _spine_track_entry_set_animation_last = + _spine_track_entry_set_animation_lastPtr + .asFunction(); + + double spine_track_entry_get_animation_time( + spine_track_entry entry, + ) { + return _spine_track_entry_get_animation_time( + entry, + ); + } + + late final _spine_track_entry_get_animation_timePtr = + _lookup>( + 'spine_track_entry_get_animation_time'); + late final _spine_track_entry_get_animation_time = + _spine_track_entry_get_animation_timePtr + .asFunction(); + + double spine_track_entry_get_time_scale( + spine_track_entry entry, + ) { + return _spine_track_entry_get_time_scale( + entry, + ); + } + + late final _spine_track_entry_get_time_scalePtr = + _lookup>( + 'spine_track_entry_get_time_scale'); + late final _spine_track_entry_get_time_scale = + _spine_track_entry_get_time_scalePtr + .asFunction(); + + void spine_track_entry_set_time_scale( + spine_track_entry entry, + double timeScale, + ) { + return _spine_track_entry_set_time_scale( + entry, + timeScale, + ); + } + + late final _spine_track_entry_set_time_scalePtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_time_scale'); + late final _spine_track_entry_set_time_scale = + _spine_track_entry_set_time_scalePtr + .asFunction(); + + double spine_track_entry_get_alpha( + spine_track_entry entry, + ) { + return _spine_track_entry_get_alpha( + entry, + ); + } + + late final _spine_track_entry_get_alphaPtr = + _lookup>( + 'spine_track_entry_get_alpha'); + late final _spine_track_entry_get_alpha = _spine_track_entry_get_alphaPtr + .asFunction(); + + void spine_track_entry_set_alpha( + spine_track_entry entry, + double alpha, + ) { + return _spine_track_entry_set_alpha( + entry, + alpha, + ); + } + + late final _spine_track_entry_set_alphaPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_alpha'); + late final _spine_track_entry_set_alpha = _spine_track_entry_set_alphaPtr + .asFunction(); + + double spine_track_entry_get_event_threshold( + spine_track_entry entry, + ) { + return _spine_track_entry_get_event_threshold( + entry, + ); + } + + late final _spine_track_entry_get_event_thresholdPtr = + _lookup>( + 'spine_track_entry_get_event_threshold'); + late final _spine_track_entry_get_event_threshold = + _spine_track_entry_get_event_thresholdPtr + .asFunction(); + + void spine_track_entry_set_event_threshold( + spine_track_entry entry, + double eventThreshold, + ) { + return _spine_track_entry_set_event_threshold( + entry, + eventThreshold, + ); + } + + late final _spine_track_entry_set_event_thresholdPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_event_threshold'); + late final _spine_track_entry_set_event_threshold = + _spine_track_entry_set_event_thresholdPtr + .asFunction(); + + double spine_track_entry_get_attachment_threshold( + spine_track_entry entry, + ) { + return _spine_track_entry_get_attachment_threshold( + entry, + ); + } + + late final _spine_track_entry_get_attachment_thresholdPtr = + _lookup>( + 'spine_track_entry_get_attachment_threshold'); + late final _spine_track_entry_get_attachment_threshold = + _spine_track_entry_get_attachment_thresholdPtr + .asFunction(); + + void spine_track_entry_set_attachment_threshold( + spine_track_entry entry, + double attachmentThreshold, + ) { + return _spine_track_entry_set_attachment_threshold( + entry, + attachmentThreshold, + ); + } + + late final _spine_track_entry_set_attachment_thresholdPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_attachment_threshold'); + late final _spine_track_entry_set_attachment_threshold = + _spine_track_entry_set_attachment_thresholdPtr + .asFunction(); + + double spine_track_entry_get_draw_order_threshold( + spine_track_entry entry, + ) { + return _spine_track_entry_get_draw_order_threshold( + entry, + ); + } + + late final _spine_track_entry_get_draw_order_thresholdPtr = + _lookup>( + 'spine_track_entry_get_draw_order_threshold'); + late final _spine_track_entry_get_draw_order_threshold = + _spine_track_entry_get_draw_order_thresholdPtr + .asFunction(); + + void spine_track_entry_set_draw_order_threshold( + spine_track_entry entry, + double drawOrderThreshold, + ) { + return _spine_track_entry_set_draw_order_threshold( + entry, + drawOrderThreshold, + ); + } + + late final _spine_track_entry_set_draw_order_thresholdPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_draw_order_threshold'); + late final _spine_track_entry_set_draw_order_threshold = + _spine_track_entry_set_draw_order_thresholdPtr + .asFunction(); + + spine_track_entry spine_track_entry_get_next( + spine_track_entry entry, + ) { + return _spine_track_entry_get_next( + entry, + ); + } + + late final _spine_track_entry_get_nextPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_get_next'); + late final _spine_track_entry_get_next = _spine_track_entry_get_nextPtr + .asFunction(); + + int spine_track_entry_is_complete( + spine_track_entry entry, + ) { + return _spine_track_entry_is_complete( + entry, + ); + } + + late final _spine_track_entry_is_completePtr = + _lookup>( + 'spine_track_entry_is_complete'); + late final _spine_track_entry_is_complete = _spine_track_entry_is_completePtr + .asFunction(); + + double spine_track_entry_get_mix_time( + spine_track_entry entry, + ) { + return _spine_track_entry_get_mix_time( + entry, + ); + } + + late final _spine_track_entry_get_mix_timePtr = + _lookup>( + 'spine_track_entry_get_mix_time'); + late final _spine_track_entry_get_mix_time = + _spine_track_entry_get_mix_timePtr + .asFunction(); + + void spine_track_entry_set_mix_time( + spine_track_entry entry, + double mixTime, + ) { + return _spine_track_entry_set_mix_time( + entry, + mixTime, + ); + } + + late final _spine_track_entry_set_mix_timePtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_mix_time'); + late final _spine_track_entry_set_mix_time = + _spine_track_entry_set_mix_timePtr + .asFunction(); + + double spine_track_entry_get_mix_duration( + spine_track_entry entry, + ) { + return _spine_track_entry_get_mix_duration( + entry, + ); + } + + late final _spine_track_entry_get_mix_durationPtr = + _lookup>( + 'spine_track_entry_get_mix_duration'); + late final _spine_track_entry_get_mix_duration = + _spine_track_entry_get_mix_durationPtr + .asFunction(); + + void spine_track_entry_set_mix_duration( + spine_track_entry entry, + double mixDuration, + ) { + return _spine_track_entry_set_mix_duration( + entry, + mixDuration, + ); + } + + late final _spine_track_entry_set_mix_durationPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_mix_duration'); + late final _spine_track_entry_set_mix_duration = + _spine_track_entry_set_mix_durationPtr + .asFunction(); + + int spine_track_entry_get_mix_blend( + spine_track_entry entry, + ) { + return _spine_track_entry_get_mix_blend( + entry, + ); + } + + late final _spine_track_entry_get_mix_blendPtr = + _lookup>( + 'spine_track_entry_get_mix_blend'); + late final _spine_track_entry_get_mix_blend = + _spine_track_entry_get_mix_blendPtr + .asFunction(); + + void spine_track_entry_set_mix_blend( + spine_track_entry entry, + int mixBlend, + ) { + return _spine_track_entry_set_mix_blend( + entry, + mixBlend, + ); + } + + late final _spine_track_entry_set_mix_blendPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_set_mix_blend'); + late final _spine_track_entry_set_mix_blend = + _spine_track_entry_set_mix_blendPtr + .asFunction(); + + spine_track_entry spine_track_entry_get_mixing_from( + spine_track_entry entry, + ) { + return _spine_track_entry_get_mixing_from( + entry, + ); + } + + late final _spine_track_entry_get_mixing_fromPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_get_mixing_from'); + late final _spine_track_entry_get_mixing_from = + _spine_track_entry_get_mixing_fromPtr + .asFunction(); + + spine_track_entry spine_track_entry_get_mixing_to( + spine_track_entry entry, + ) { + return _spine_track_entry_get_mixing_to( + entry, + ); + } + + late final _spine_track_entry_get_mixing_toPtr = _lookup< + ffi.NativeFunction>( + 'spine_track_entry_get_mixing_to'); + late final _spine_track_entry_get_mixing_to = + _spine_track_entry_get_mixing_toPtr + .asFunction(); + + void spine_track_entry_reset_rotation_directions( + spine_track_entry entry, + ) { + return _spine_track_entry_reset_rotation_directions( + entry, + ); + } + + late final _spine_track_entry_reset_rotation_directionsPtr = + _lookup>( + 'spine_track_entry_reset_rotation_directions'); + late final _spine_track_entry_reset_rotation_directions = + _spine_track_entry_reset_rotation_directionsPtr + .asFunction(); + + double spine_track_entry_get_track_complete( + spine_track_entry entry, + ) { + return _spine_track_entry_get_track_complete( + entry, + ); + } + + late final _spine_track_entry_get_track_completePtr = + _lookup>( + 'spine_track_entry_get_track_complete'); + late final _spine_track_entry_get_track_complete = + _spine_track_entry_get_track_completePtr + .asFunction(); + + /// OMITTED setListener() + /// OMITTED setListener() + void spine_skeleton_update_cache( + spine_skeleton skeleton, + ) { + return _spine_skeleton_update_cache( + skeleton, + ); + } + + late final _spine_skeleton_update_cachePtr = + _lookup>( + 'spine_skeleton_update_cache'); + late final _spine_skeleton_update_cache = _spine_skeleton_update_cachePtr + .asFunction(); + + /// OMITTED printUpdateCache() + void spine_skeleton_update_world_transform( + spine_skeleton skeleton, + ) { + return _spine_skeleton_update_world_transform( + skeleton, + ); + } + + late final _spine_skeleton_update_world_transformPtr = + _lookup>( + 'spine_skeleton_update_world_transform'); + late final _spine_skeleton_update_world_transform = + _spine_skeleton_update_world_transformPtr + .asFunction(); + + void spine_skeleton_update_world_transform_bone( + spine_skeleton skeleton, + spine_bone parent, + ) { + return _spine_skeleton_update_world_transform_bone( + skeleton, + parent, + ); + } + + late final _spine_skeleton_update_world_transform_bonePtr = _lookup< + ffi.NativeFunction>( + 'spine_skeleton_update_world_transform_bone'); + late final _spine_skeleton_update_world_transform_bone = + _spine_skeleton_update_world_transform_bonePtr + .asFunction(); + + void spine_skeleton_set_to_setup_pose( + spine_skeleton skeleton, + ) { + return _spine_skeleton_set_to_setup_pose( + skeleton, + ); + } + + late final _spine_skeleton_set_to_setup_posePtr = + _lookup>( + 'spine_skeleton_set_to_setup_pose'); + late final _spine_skeleton_set_to_setup_pose = + _spine_skeleton_set_to_setup_posePtr + .asFunction(); + + void spine_skeleton_set_bones_to_setup_pose( + spine_skeleton skeleton, + ) { + return _spine_skeleton_set_bones_to_setup_pose( + skeleton, + ); + } + + late final _spine_skeleton_set_bones_to_setup_posePtr = + _lookup>( + 'spine_skeleton_set_bones_to_setup_pose'); + late final _spine_skeleton_set_bones_to_setup_pose = + _spine_skeleton_set_bones_to_setup_posePtr + .asFunction(); + + void spine_skeleton_set_slots_to_setup_pose( + spine_skeleton skeleton, + ) { + return _spine_skeleton_set_slots_to_setup_pose( + skeleton, + ); + } + + late final _spine_skeleton_set_slots_to_setup_posePtr = + _lookup>( + 'spine_skeleton_set_slots_to_setup_pose'); + late final _spine_skeleton_set_slots_to_setup_pose = + _spine_skeleton_set_slots_to_setup_posePtr + .asFunction(); + + spine_bone spine_skeleton_find_bone( + spine_skeleton skeleton, + ffi.Pointer boneName, + ) { + return _spine_skeleton_find_bone( + skeleton, + boneName, + ); + } + + late final _spine_skeleton_find_bonePtr = _lookup< + ffi.NativeFunction< + spine_bone Function( + spine_skeleton, ffi.Pointer)>>('spine_skeleton_find_bone'); + late final _spine_skeleton_find_bone = _spine_skeleton_find_bonePtr + .asFunction)>(); + + spine_slot spine_skeleton_find_slot( + spine_skeleton skeleton, + ffi.Pointer slotName, + ) { + return _spine_skeleton_find_slot( + skeleton, + slotName, + ); + } + + late final _spine_skeleton_find_slotPtr = _lookup< + ffi.NativeFunction< + spine_slot Function( + spine_skeleton, ffi.Pointer)>>('spine_skeleton_find_slot'); + late final _spine_skeleton_find_slot = _spine_skeleton_find_slotPtr + .asFunction)>(); + + void spine_skeleton_set_skin_by_name( + spine_skeleton skeleton, + ffi.Pointer skinName, + ) { + return _spine_skeleton_set_skin_by_name( + skeleton, + skinName, + ); + } + + late final _spine_skeleton_set_skin_by_namePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_set_skin_by_name'); + late final _spine_skeleton_set_skin_by_name = + _spine_skeleton_set_skin_by_namePtr + .asFunction)>(); + + void spine_skeleton_set_skin( + spine_skeleton skeleton, + spine_skin skin, + ) { + return _spine_skeleton_set_skin( + skeleton, + skin, + ); + } + + late final _spine_skeleton_set_skinPtr = _lookup< + ffi.NativeFunction>( + 'spine_skeleton_set_skin'); + late final _spine_skeleton_set_skin = _spine_skeleton_set_skinPtr + .asFunction(); + + spine_attachment spine_skeleton_get_attachment_by_name( + spine_skeleton skeleton, + ffi.Pointer slotName, + ffi.Pointer attachmentName, + ) { + return _spine_skeleton_get_attachment_by_name( + skeleton, + slotName, + attachmentName, + ); + } + + late final _spine_skeleton_get_attachment_by_namePtr = _lookup< + ffi.NativeFunction< + spine_attachment Function(spine_skeleton, ffi.Pointer, + ffi.Pointer)>>('spine_skeleton_get_attachment_by_name'); + late final _spine_skeleton_get_attachment_by_name = + _spine_skeleton_get_attachment_by_namePtr.asFunction< + spine_attachment Function( + spine_skeleton, ffi.Pointer, ffi.Pointer)>(); + + spine_attachment spine_skeleton_get_attachment( + spine_skeleton skeleton, + int slotIndex, + ffi.Pointer attachmentName, + ) { + return _spine_skeleton_get_attachment( + skeleton, + slotIndex, + attachmentName, + ); + } + + late final _spine_skeleton_get_attachmentPtr = _lookup< + ffi.NativeFunction< + spine_attachment Function(spine_skeleton, ffi.Int32, + ffi.Pointer)>>('spine_skeleton_get_attachment'); + late final _spine_skeleton_get_attachment = + _spine_skeleton_get_attachmentPtr.asFunction< + spine_attachment Function(spine_skeleton, int, ffi.Pointer)>(); + + void spine_skeleton_set_attachment( + spine_skeleton skeleton, + ffi.Pointer slotName, + ffi.Pointer attachmentName, + ) { + return _spine_skeleton_set_attachment( + skeleton, + slotName, + attachmentName, + ); + } + + late final _spine_skeleton_set_attachmentPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Pointer, + ffi.Pointer)>>('spine_skeleton_set_attachment'); + late final _spine_skeleton_set_attachment = + _spine_skeleton_set_attachmentPtr.asFunction< + void Function( + spine_skeleton, ffi.Pointer, ffi.Pointer)>(); + + spine_ik_constraint spine_skeleton_find_ik_constraint( + spine_skeleton skeleton, + ffi.Pointer constraintName, + ) { + return _spine_skeleton_find_ik_constraint( + skeleton, + constraintName, + ); + } + + late final _spine_skeleton_find_ik_constraintPtr = _lookup< + ffi.NativeFunction< + spine_ik_constraint Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_ik_constraint'); + late final _spine_skeleton_find_ik_constraint = + _spine_skeleton_find_ik_constraintPtr.asFunction< + spine_ik_constraint Function(spine_skeleton, ffi.Pointer)>(); + + spine_transform_constraint spine_skeleton_find_transform_constraint( + spine_skeleton skeleton, + ffi.Pointer constraintName, + ) { + return _spine_skeleton_find_transform_constraint( + skeleton, + constraintName, + ); + } + + late final _spine_skeleton_find_transform_constraintPtr = _lookup< + ffi.NativeFunction< + spine_transform_constraint Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_transform_constraint'); + late final _spine_skeleton_find_transform_constraint = + _spine_skeleton_find_transform_constraintPtr.asFunction< + spine_transform_constraint Function( + spine_skeleton, ffi.Pointer)>(); + + spine_path_constraint spine_skeleton_find_path_constraint( + spine_skeleton skeleton, + ffi.Pointer constraintName, + ) { + return _spine_skeleton_find_path_constraint( + skeleton, + constraintName, + ); + } + + late final _spine_skeleton_find_path_constraintPtr = _lookup< + ffi.NativeFunction< + spine_path_constraint Function(spine_skeleton, + ffi.Pointer)>>('spine_skeleton_find_path_constraint'); + late final _spine_skeleton_find_path_constraint = + _spine_skeleton_find_path_constraintPtr.asFunction< + spine_path_constraint Function(spine_skeleton, ffi.Pointer)>(); + + spine_bounds spine_skeleton_get_bounds( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_bounds( + skeleton, + ); + } + + late final _spine_skeleton_get_boundsPtr = + _lookup>( + 'spine_skeleton_get_bounds'); + late final _spine_skeleton_get_bounds = _spine_skeleton_get_boundsPtr + .asFunction(); + + spine_bone spine_skeleton_get_root_bone( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_root_bone( + skeleton, + ); + } + + late final _spine_skeleton_get_root_bonePtr = + _lookup>( + 'spine_skeleton_get_root_bone'); + late final _spine_skeleton_get_root_bone = _spine_skeleton_get_root_bonePtr + .asFunction(); + + spine_skeleton_data spine_skeleton_get_data( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_data( + skeleton, + ); + } + + late final _spine_skeleton_get_dataPtr = + _lookup>( + 'spine_skeleton_get_data'); + late final _spine_skeleton_get_data = _spine_skeleton_get_dataPtr + .asFunction(); + + int spine_skeleton_get_num_bones( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_bones( + skeleton, + ); + } + + late final _spine_skeleton_get_num_bonesPtr = + _lookup>( + 'spine_skeleton_get_num_bones'); + late final _spine_skeleton_get_num_bones = _spine_skeleton_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_bones( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_bones( + skeleton, + ); + } + + late final _spine_skeleton_get_bonesPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton)>>( + 'spine_skeleton_get_bones'); + late final _spine_skeleton_get_bones = _spine_skeleton_get_bonesPtr + .asFunction Function(spine_skeleton)>(); + + /// OMITTED getUpdateCacheList() + int spine_skeleton_get_num_slots( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_slots( + skeleton, + ); + } + + late final _spine_skeleton_get_num_slotsPtr = + _lookup>( + 'spine_skeleton_get_num_slots'); + late final _spine_skeleton_get_num_slots = _spine_skeleton_get_num_slotsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_slots( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_slots( + skeleton, + ); + } + + late final _spine_skeleton_get_slotsPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton)>>( + 'spine_skeleton_get_slots'); + late final _spine_skeleton_get_slots = _spine_skeleton_get_slotsPtr + .asFunction Function(spine_skeleton)>(); + + int spine_skeleton_get_num_draw_order( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_draw_order( + skeleton, + ); + } + + late final _spine_skeleton_get_num_draw_orderPtr = + _lookup>( + 'spine_skeleton_get_num_draw_order'); + late final _spine_skeleton_get_num_draw_order = + _spine_skeleton_get_num_draw_orderPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_draw_order( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_draw_order( + skeleton, + ); + } + + late final _spine_skeleton_get_draw_orderPtr = _lookup< + ffi.NativeFunction Function(spine_skeleton)>>( + 'spine_skeleton_get_draw_order'); + late final _spine_skeleton_get_draw_order = _spine_skeleton_get_draw_orderPtr + .asFunction Function(spine_skeleton)>(); + + int spine_skeleton_get_num_ik_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_ik_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_num_ik_constraintsPtr = + _lookup>( + 'spine_skeleton_get_num_ik_constraints'); + late final _spine_skeleton_get_num_ik_constraints = + _spine_skeleton_get_num_ik_constraintsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_ik_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_ik_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_ik_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton)>>('spine_skeleton_get_ik_constraints'); + late final _spine_skeleton_get_ik_constraints = + _spine_skeleton_get_ik_constraintsPtr.asFunction< + ffi.Pointer Function(spine_skeleton)>(); + + int spine_skeleton_get_num_transform_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_transform_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_num_transform_constraintsPtr = + _lookup>( + 'spine_skeleton_get_num_transform_constraints'); + late final _spine_skeleton_get_num_transform_constraints = + _spine_skeleton_get_num_transform_constraintsPtr + .asFunction(); + + ffi.Pointer + spine_skeleton_get_transform_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_transform_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_transform_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton)>>('spine_skeleton_get_transform_constraints'); + late final _spine_skeleton_get_transform_constraints = + _spine_skeleton_get_transform_constraintsPtr.asFunction< + ffi.Pointer Function(spine_skeleton)>(); + + int spine_skeleton_get_num_path_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_num_path_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_num_path_constraintsPtr = + _lookup>( + 'spine_skeleton_get_num_path_constraints'); + late final _spine_skeleton_get_num_path_constraints = + _spine_skeleton_get_num_path_constraintsPtr + .asFunction(); + + ffi.Pointer spine_skeleton_get_path_constraints( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_path_constraints( + skeleton, + ); + } + + late final _spine_skeleton_get_path_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skeleton)>>('spine_skeleton_get_path_constraints'); + late final _spine_skeleton_get_path_constraints = + _spine_skeleton_get_path_constraintsPtr.asFunction< + ffi.Pointer Function(spine_skeleton)>(); + + spine_skin spine_skeleton_get_skin( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_skin( + skeleton, + ); + } + + late final _spine_skeleton_get_skinPtr = + _lookup>( + 'spine_skeleton_get_skin'); + late final _spine_skeleton_get_skin = _spine_skeleton_get_skinPtr + .asFunction(); + + spine_color spine_skeleton_get_color( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_color( + skeleton, + ); + } + + late final _spine_skeleton_get_colorPtr = + _lookup>( + 'spine_skeleton_get_color'); + late final _spine_skeleton_get_color = _spine_skeleton_get_colorPtr + .asFunction(); + + void spine_skeleton_set_color( + spine_skeleton skeleton, + double r, + double g, + double b, + double a, + ) { + return _spine_skeleton_set_color( + skeleton, + r, + g, + b, + a, + ); + } + + late final _spine_skeleton_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_skeleton_set_color'); + late final _spine_skeleton_set_color = + _spine_skeleton_set_colorPtr.asFunction< + void Function(spine_skeleton, double, double, double, double)>(); + + void spine_skeleton_set_position( + spine_skeleton skeleton, + double x, + double y, + ) { + return _spine_skeleton_set_position( + skeleton, + x, + y, + ); + } + + late final _spine_skeleton_set_positionPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skeleton, ffi.Float, + ffi.Float)>>('spine_skeleton_set_position'); + late final _spine_skeleton_set_position = _spine_skeleton_set_positionPtr + .asFunction(); + + double spine_skeleton_get_x( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_x( + skeleton, + ); + } + + late final _spine_skeleton_get_xPtr = + _lookup>( + 'spine_skeleton_get_x'); + late final _spine_skeleton_get_x = + _spine_skeleton_get_xPtr.asFunction(); + + void spine_skeleton_set_x( + spine_skeleton skeleton, + double x, + ) { + return _spine_skeleton_set_x( + skeleton, + x, + ); + } + + late final _spine_skeleton_set_xPtr = + _lookup>( + 'spine_skeleton_set_x'); + late final _spine_skeleton_set_x = _spine_skeleton_set_xPtr + .asFunction(); + + double spine_skeleton_get_y( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_y( + skeleton, + ); + } + + late final _spine_skeleton_get_yPtr = + _lookup>( + 'spine_skeleton_get_y'); + late final _spine_skeleton_get_y = + _spine_skeleton_get_yPtr.asFunction(); + + void spine_skeleton_set_y( + spine_skeleton skeleton, + double y, + ) { + return _spine_skeleton_set_y( + skeleton, + y, + ); + } + + late final _spine_skeleton_set_yPtr = + _lookup>( + 'spine_skeleton_set_y'); + late final _spine_skeleton_set_y = _spine_skeleton_set_yPtr + .asFunction(); + + double spine_skeleton_get_scale_x( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_scale_x( + skeleton, + ); + } + + late final _spine_skeleton_get_scale_xPtr = + _lookup>( + 'spine_skeleton_get_scale_x'); + late final _spine_skeleton_get_scale_x = _spine_skeleton_get_scale_xPtr + .asFunction(); + + void spine_skeleton_set_scale_x( + spine_skeleton skeleton, + double scaleX, + ) { + return _spine_skeleton_set_scale_x( + skeleton, + scaleX, + ); + } + + late final _spine_skeleton_set_scale_xPtr = + _lookup>( + 'spine_skeleton_set_scale_x'); + late final _spine_skeleton_set_scale_x = _spine_skeleton_set_scale_xPtr + .asFunction(); + + double spine_skeleton_get_scale_y( + spine_skeleton skeleton, + ) { + return _spine_skeleton_get_scale_y( + skeleton, + ); + } + + late final _spine_skeleton_get_scale_yPtr = + _lookup>( + 'spine_skeleton_get_scale_y'); + late final _spine_skeleton_get_scale_y = _spine_skeleton_get_scale_yPtr + .asFunction(); + + void spine_skeleton_set_scale_y( + spine_skeleton skeleton, + double scaleY, + ) { + return _spine_skeleton_set_scale_y( + skeleton, + scaleY, + ); + } + + late final _spine_skeleton_set_scale_yPtr = + _lookup>( + 'spine_skeleton_set_scale_y'); + late final _spine_skeleton_set_scale_y = _spine_skeleton_set_scale_yPtr + .asFunction(); + + ffi.Pointer spine_event_data_get_name( + spine_event_data event, + ) { + return _spine_event_data_get_name( + event, + ); + } + + late final _spine_event_data_get_namePtr = + _lookup Function(spine_event_data)>>( + 'spine_event_data_get_name'); + late final _spine_event_data_get_name = _spine_event_data_get_namePtr + .asFunction Function(spine_event_data)>(); + + int spine_event_data_get_int_value( + spine_event_data event, + ) { + return _spine_event_data_get_int_value( + event, + ); + } + + late final _spine_event_data_get_int_valuePtr = + _lookup>( + 'spine_event_data_get_int_value'); + late final _spine_event_data_get_int_value = + _spine_event_data_get_int_valuePtr + .asFunction(); + + void spine_event_data_set_int_value( + spine_event_data event, + int value, + ) { + return _spine_event_data_set_int_value( + event, + value, + ); + } + + late final _spine_event_data_set_int_valuePtr = _lookup< + ffi.NativeFunction>( + 'spine_event_data_set_int_value'); + late final _spine_event_data_set_int_value = + _spine_event_data_set_int_valuePtr + .asFunction(); + + double spine_event_data_get_float_value( + spine_event_data event, + ) { + return _spine_event_data_get_float_value( + event, + ); + } + + late final _spine_event_data_get_float_valuePtr = + _lookup>( + 'spine_event_data_get_float_value'); + late final _spine_event_data_get_float_value = + _spine_event_data_get_float_valuePtr + .asFunction(); + + void spine_event_data_set_float_value( + spine_event_data event, + double value, + ) { + return _spine_event_data_set_float_value( + event, + value, + ); + } + + late final _spine_event_data_set_float_valuePtr = _lookup< + ffi.NativeFunction>( + 'spine_event_data_set_float_value'); + late final _spine_event_data_set_float_value = + _spine_event_data_set_float_valuePtr + .asFunction(); + + ffi.Pointer spine_event_data_get_string_value( + spine_event_data event, + ) { + return _spine_event_data_get_string_value( + event, + ); + } + + late final _spine_event_data_get_string_valuePtr = + _lookup Function(spine_event_data)>>( + 'spine_event_data_get_string_value'); + late final _spine_event_data_get_string_value = + _spine_event_data_get_string_valuePtr + .asFunction Function(spine_event_data)>(); + + void spine_event_data_set_string_value( + spine_event_data event, + ffi.Pointer value, + ) { + return _spine_event_data_set_string_value( + event, + value, + ); + } + + late final _spine_event_data_set_string_valuePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_event_data, + ffi.Pointer)>>('spine_event_data_set_string_value'); + late final _spine_event_data_set_string_value = + _spine_event_data_set_string_valuePtr + .asFunction)>(); + + ffi.Pointer spine_event_data_get_audio_path( + spine_event_data event, + ) { + return _spine_event_data_get_audio_path( + event, + ); + } + + late final _spine_event_data_get_audio_pathPtr = + _lookup Function(spine_event_data)>>( + 'spine_event_data_get_audio_path'); + late final _spine_event_data_get_audio_path = + _spine_event_data_get_audio_pathPtr + .asFunction Function(spine_event_data)>(); + + /// OMITTED setAudioPath() + double spine_event_data_get_volume( + spine_event_data event, + ) { + return _spine_event_data_get_volume( + event, + ); + } + + late final _spine_event_data_get_volumePtr = + _lookup>( + 'spine_event_data_get_volume'); + late final _spine_event_data_get_volume = _spine_event_data_get_volumePtr + .asFunction(); + + void spine_event_data_set_volume( + spine_event_data event, + double volume, + ) { + return _spine_event_data_set_volume( + event, + volume, + ); + } + + late final _spine_event_data_set_volumePtr = _lookup< + ffi.NativeFunction>( + 'spine_event_data_set_volume'); + late final _spine_event_data_set_volume = _spine_event_data_set_volumePtr + .asFunction(); + + double spine_event_data_get_balance( + spine_event_data event, + ) { + return _spine_event_data_get_balance( + event, + ); + } + + late final _spine_event_data_get_balancePtr = + _lookup>( + 'spine_event_data_get_balance'); + late final _spine_event_data_get_balance = _spine_event_data_get_balancePtr + .asFunction(); + + void spine_event_data_set_balance( + spine_event_data event, + double balance, + ) { + return _spine_event_data_set_balance( + event, + balance, + ); + } + + late final _spine_event_data_set_balancePtr = _lookup< + ffi.NativeFunction>( + 'spine_event_data_set_balance'); + late final _spine_event_data_set_balance = _spine_event_data_set_balancePtr + .asFunction(); + + spine_event_data spine_event_get_data( + spine_event event, + ) { + return _spine_event_get_data( + event, + ); + } + + late final _spine_event_get_dataPtr = + _lookup>( + 'spine_event_get_data'); + late final _spine_event_get_data = _spine_event_get_dataPtr + .asFunction(); + + double spine_event_get_time( + spine_event event, + ) { + return _spine_event_get_time( + event, + ); + } + + late final _spine_event_get_timePtr = + _lookup>( + 'spine_event_get_time'); + late final _spine_event_get_time = + _spine_event_get_timePtr.asFunction(); + + int spine_event_get_int_value( + spine_event event, + ) { + return _spine_event_get_int_value( + event, + ); + } + + late final _spine_event_get_int_valuePtr = + _lookup>( + 'spine_event_get_int_value'); + late final _spine_event_get_int_value = + _spine_event_get_int_valuePtr.asFunction(); + + void spine_event_set_int_value( + spine_event event, + int value, + ) { + return _spine_event_set_int_value( + event, + value, + ); + } + + late final _spine_event_set_int_valuePtr = + _lookup>( + 'spine_event_set_int_value'); + late final _spine_event_set_int_value = _spine_event_set_int_valuePtr + .asFunction(); + + double spine_event_get_float_value( + spine_event event, + ) { + return _spine_event_get_float_value( + event, + ); + } + + late final _spine_event_get_float_valuePtr = + _lookup>( + 'spine_event_get_float_value'); + late final _spine_event_get_float_value = _spine_event_get_float_valuePtr + .asFunction(); + + void spine_event_set_float_value( + spine_event event, + double value, + ) { + return _spine_event_set_float_value( + event, + value, + ); + } + + late final _spine_event_set_float_valuePtr = + _lookup>( + 'spine_event_set_float_value'); + late final _spine_event_set_float_value = _spine_event_set_float_valuePtr + .asFunction(); + + ffi.Pointer spine_event_get_string_value( + spine_event event, + ) { + return _spine_event_get_string_value( + event, + ); + } + + late final _spine_event_get_string_valuePtr = + _lookup Function(spine_event)>>( + 'spine_event_get_string_value'); + late final _spine_event_get_string_value = _spine_event_get_string_valuePtr + .asFunction Function(spine_event)>(); + + void spine_event_set_string_value( + spine_event event, + ffi.Pointer value, + ) { + return _spine_event_set_string_value( + event, + value, + ); + } + + late final _spine_event_set_string_valuePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_event, ffi.Pointer)>>('spine_event_set_string_value'); + late final _spine_event_set_string_value = _spine_event_set_string_valuePtr + .asFunction)>(); + + double spine_event_get_volume( + spine_event event, + ) { + return _spine_event_get_volume( + event, + ); + } + + late final _spine_event_get_volumePtr = + _lookup>( + 'spine_event_get_volume'); + late final _spine_event_get_volume = + _spine_event_get_volumePtr.asFunction(); + + void spine_event_set_volume( + spine_event event, + double volume, + ) { + return _spine_event_set_volume( + event, + volume, + ); + } + + late final _spine_event_set_volumePtr = + _lookup>( + 'spine_event_set_volume'); + late final _spine_event_set_volume = _spine_event_set_volumePtr + .asFunction(); + + double spine_event_get_balance( + spine_event event, + ) { + return _spine_event_get_balance( + event, + ); + } + + late final _spine_event_get_balancePtr = + _lookup>( + 'spine_event_get_balance'); + late final _spine_event_get_balance = + _spine_event_get_balancePtr.asFunction(); + + void spine_event_set_balance( + spine_event event, + double balance, + ) { + return _spine_event_set_balance( + event, + balance, + ); + } + + late final _spine_event_set_balancePtr = + _lookup>( + 'spine_event_set_balance'); + late final _spine_event_set_balance = _spine_event_set_balancePtr + .asFunction(); + + int spine_slot_data_get_index( + spine_slot_data slot, + ) { + return _spine_slot_data_get_index( + slot, + ); + } + + late final _spine_slot_data_get_indexPtr = + _lookup>( + 'spine_slot_data_get_index'); + late final _spine_slot_data_get_index = + _spine_slot_data_get_indexPtr.asFunction(); + + ffi.Pointer spine_slot_data_get_name( + spine_slot_data slot, + ) { + return _spine_slot_data_get_name( + slot, + ); + } + + late final _spine_slot_data_get_namePtr = + _lookup Function(spine_slot_data)>>( + 'spine_slot_data_get_name'); + late final _spine_slot_data_get_name = _spine_slot_data_get_namePtr + .asFunction Function(spine_slot_data)>(); + + spine_bone_data spine_slot_data_get_bone_data( + spine_slot_data slot, + ) { + return _spine_slot_data_get_bone_data( + slot, + ); + } + + late final _spine_slot_data_get_bone_dataPtr = + _lookup>( + 'spine_slot_data_get_bone_data'); + late final _spine_slot_data_get_bone_data = _spine_slot_data_get_bone_dataPtr + .asFunction(); + + spine_color spine_slot_data_get_color( + spine_slot_data slot, + ) { + return _spine_slot_data_get_color( + slot, + ); + } + + late final _spine_slot_data_get_colorPtr = + _lookup>( + 'spine_slot_data_get_color'); + late final _spine_slot_data_get_color = _spine_slot_data_get_colorPtr + .asFunction(); + + void spine_slot_data_set_color( + spine_slot_data slot, + double r, + double g, + double b, + double a, + ) { + return _spine_slot_data_set_color( + slot, + r, + g, + b, + a, + ); + } + + late final _spine_slot_data_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_slot_data, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_slot_data_set_color'); + late final _spine_slot_data_set_color = + _spine_slot_data_set_colorPtr.asFunction< + void Function(spine_slot_data, double, double, double, double)>(); + + spine_color spine_slot_data_get_dark_color( + spine_slot_data slot, + ) { + return _spine_slot_data_get_dark_color( + slot, + ); + } + + late final _spine_slot_data_get_dark_colorPtr = + _lookup>( + 'spine_slot_data_get_dark_color'); + late final _spine_slot_data_get_dark_color = + _spine_slot_data_get_dark_colorPtr + .asFunction(); + + void spine_slot_data_set_dark_color( + spine_slot_data slot, + double r, + double g, + double b, + double a, + ) { + return _spine_slot_data_set_dark_color( + slot, + r, + g, + b, + a, + ); + } + + late final _spine_slot_data_set_dark_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_slot_data, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_slot_data_set_dark_color'); + late final _spine_slot_data_set_dark_color = + _spine_slot_data_set_dark_colorPtr.asFunction< + void Function(spine_slot_data, double, double, double, double)>(); + + int spine_slot_data_has_dark_color( + spine_slot_data slot, + ) { + return _spine_slot_data_has_dark_color( + slot, + ); + } + + late final _spine_slot_data_has_dark_colorPtr = + _lookup>( + 'spine_slot_data_has_dark_color'); + late final _spine_slot_data_has_dark_color = + _spine_slot_data_has_dark_colorPtr + .asFunction(); + + void spine_slot_data_set_has_dark_color( + spine_slot_data slot, + int hasDarkColor, + ) { + return _spine_slot_data_set_has_dark_color( + slot, + hasDarkColor, + ); + } + + late final _spine_slot_data_set_has_dark_colorPtr = _lookup< + ffi.NativeFunction>( + 'spine_slot_data_set_has_dark_color'); + late final _spine_slot_data_set_has_dark_color = + _spine_slot_data_set_has_dark_colorPtr + .asFunction(); + + ffi.Pointer spine_slot_data_get_attachment_name( + spine_slot_data slot, + ) { + return _spine_slot_data_get_attachment_name( + slot, + ); + } + + late final _spine_slot_data_get_attachment_namePtr = + _lookup Function(spine_slot_data)>>( + 'spine_slot_data_get_attachment_name'); + late final _spine_slot_data_get_attachment_name = + _spine_slot_data_get_attachment_namePtr + .asFunction Function(spine_slot_data)>(); + + void spine_slot_data_set_attachment_name( + spine_slot_data slot, + ffi.Pointer attachmentName, + ) { + return _spine_slot_data_set_attachment_name( + slot, + attachmentName, + ); + } + + late final _spine_slot_data_set_attachment_namePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_slot_data, + ffi.Pointer)>>('spine_slot_data_set_attachment_name'); + late final _spine_slot_data_set_attachment_name = + _spine_slot_data_set_attachment_namePtr + .asFunction)>(); + + int spine_slot_data_get_blend_mode( + spine_slot_data slot, + ) { + return _spine_slot_data_get_blend_mode( + slot, + ); + } + + late final _spine_slot_data_get_blend_modePtr = + _lookup>( + 'spine_slot_data_get_blend_mode'); + late final _spine_slot_data_get_blend_mode = + _spine_slot_data_get_blend_modePtr + .asFunction(); + + void spine_slot_data_set_blend_mode( + spine_slot_data slot, + int blendMode, + ) { + return _spine_slot_data_set_blend_mode( + slot, + blendMode, + ); + } + + late final _spine_slot_data_set_blend_modePtr = _lookup< + ffi.NativeFunction>( + 'spine_slot_data_set_blend_mode'); + late final _spine_slot_data_set_blend_mode = + _spine_slot_data_set_blend_modePtr + .asFunction(); + + void spine_slot_set_to_setup_pose( + spine_slot slot, + ) { + return _spine_slot_set_to_setup_pose( + slot, + ); + } + + late final _spine_slot_set_to_setup_posePtr = + _lookup>( + 'spine_slot_set_to_setup_pose'); + late final _spine_slot_set_to_setup_pose = + _spine_slot_set_to_setup_posePtr.asFunction(); + + spine_slot_data spine_slot_get_data( + spine_slot slot, + ) { + return _spine_slot_get_data( + slot, + ); + } + + late final _spine_slot_get_dataPtr = + _lookup>( + 'spine_slot_get_data'); + late final _spine_slot_get_data = _spine_slot_get_dataPtr + .asFunction(); + + spine_bone spine_slot_get_bone( + spine_slot slot, + ) { + return _spine_slot_get_bone( + slot, + ); + } + + late final _spine_slot_get_bonePtr = + _lookup>( + 'spine_slot_get_bone'); + late final _spine_slot_get_bone = + _spine_slot_get_bonePtr.asFunction(); + + spine_skeleton spine_slot_get_skeleton( + spine_slot slot, + ) { + return _spine_slot_get_skeleton( + slot, + ); + } + + late final _spine_slot_get_skeletonPtr = + _lookup>( + 'spine_slot_get_skeleton'); + late final _spine_slot_get_skeleton = _spine_slot_get_skeletonPtr + .asFunction(); + + spine_color spine_slot_get_color( + spine_slot slot, + ) { + return _spine_slot_get_color( + slot, + ); + } + + late final _spine_slot_get_colorPtr = + _lookup>( + 'spine_slot_get_color'); + late final _spine_slot_get_color = + _spine_slot_get_colorPtr.asFunction(); + + void spine_slot_set_color( + spine_slot slot, + double r, + double g, + double b, + double a, + ) { + return _spine_slot_set_color( + slot, + r, + g, + b, + a, + ); + } + + late final _spine_slot_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_slot, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_slot_set_color'); + late final _spine_slot_set_color = _spine_slot_set_colorPtr + .asFunction(); + + spine_color spine_slot_get_dark_color( + spine_slot slot, + ) { + return _spine_slot_get_dark_color( + slot, + ); + } + + late final _spine_slot_get_dark_colorPtr = + _lookup>( + 'spine_slot_get_dark_color'); + late final _spine_slot_get_dark_color = _spine_slot_get_dark_colorPtr + .asFunction(); + + void spine_slot_set_dark_color( + spine_slot slot, + double r, + double g, + double b, + double a, + ) { + return _spine_slot_set_dark_color( + slot, + r, + g, + b, + a, + ); + } + + late final _spine_slot_set_dark_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_slot, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_slot_set_dark_color'); + late final _spine_slot_set_dark_color = _spine_slot_set_dark_colorPtr + .asFunction(); + + int spine_slot_has_dark_color( + spine_slot slot, + ) { + return _spine_slot_has_dark_color( + slot, + ); + } + + late final _spine_slot_has_dark_colorPtr = + _lookup>( + 'spine_slot_has_dark_color'); + late final _spine_slot_has_dark_color = + _spine_slot_has_dark_colorPtr.asFunction(); + + spine_attachment spine_slot_get_attachment( + spine_slot slot, + ) { + return _spine_slot_get_attachment( + slot, + ); + } + + late final _spine_slot_get_attachmentPtr = + _lookup>( + 'spine_slot_get_attachment'); + late final _spine_slot_get_attachment = _spine_slot_get_attachmentPtr + .asFunction(); + + void spine_slot_set_attachment( + spine_slot slot, + spine_attachment attachment, + ) { + return _spine_slot_set_attachment( + slot, + attachment, + ); + } + + late final _spine_slot_set_attachmentPtr = _lookup< + ffi.NativeFunction>( + 'spine_slot_set_attachment'); + late final _spine_slot_set_attachment = _spine_slot_set_attachmentPtr + .asFunction(); + + /// OMITTED getDeform() + int spine_slot_get_sequence_index( + spine_slot slot, + ) { + return _spine_slot_get_sequence_index( + slot, + ); + } + + late final _spine_slot_get_sequence_indexPtr = + _lookup>( + 'spine_slot_get_sequence_index'); + late final _spine_slot_get_sequence_index = + _spine_slot_get_sequence_indexPtr.asFunction(); + + void spine_slot_set_sequence_index( + spine_slot slot, + int sequenceIndex, + ) { + return _spine_slot_set_sequence_index( + slot, + sequenceIndex, + ); + } + + late final _spine_slot_set_sequence_indexPtr = + _lookup>( + 'spine_slot_set_sequence_index'); + late final _spine_slot_set_sequence_index = _spine_slot_set_sequence_indexPtr + .asFunction(); + + int spine_bone_data_get_index( + spine_bone_data data, + ) { + return _spine_bone_data_get_index( + data, + ); + } + + late final _spine_bone_data_get_indexPtr = + _lookup>( + 'spine_bone_data_get_index'); + late final _spine_bone_data_get_index = + _spine_bone_data_get_indexPtr.asFunction(); + + ffi.Pointer spine_bone_data_get_name( + spine_bone_data data, + ) { + return _spine_bone_data_get_name( + data, + ); + } + + late final _spine_bone_data_get_namePtr = + _lookup Function(spine_bone_data)>>( + 'spine_bone_data_get_name'); + late final _spine_bone_data_get_name = _spine_bone_data_get_namePtr + .asFunction Function(spine_bone_data)>(); + + spine_bone_data spine_bone_data_get_parent( + spine_bone_data data, + ) { + return _spine_bone_data_get_parent( + data, + ); + } + + late final _spine_bone_data_get_parentPtr = + _lookup>( + 'spine_bone_data_get_parent'); + late final _spine_bone_data_get_parent = _spine_bone_data_get_parentPtr + .asFunction(); + + double spine_bone_data_get_length( + spine_bone_data data, + ) { + return _spine_bone_data_get_length( + data, + ); + } + + late final _spine_bone_data_get_lengthPtr = + _lookup>( + 'spine_bone_data_get_length'); + late final _spine_bone_data_get_length = _spine_bone_data_get_lengthPtr + .asFunction(); + + void spine_bone_data_set_length( + spine_bone_data data, + double length, + ) { + return _spine_bone_data_set_length( + data, + length, + ); + } + + late final _spine_bone_data_set_lengthPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_length'); + late final _spine_bone_data_set_length = _spine_bone_data_set_lengthPtr + .asFunction(); + + double spine_bone_data_get_x( + spine_bone_data data, + ) { + return _spine_bone_data_get_x( + data, + ); + } + + late final _spine_bone_data_get_xPtr = + _lookup>( + 'spine_bone_data_get_x'); + late final _spine_bone_data_get_x = + _spine_bone_data_get_xPtr.asFunction(); + + void spine_bone_data_set_x( + spine_bone_data data, + double x, + ) { + return _spine_bone_data_set_x( + data, + x, + ); + } + + late final _spine_bone_data_set_xPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_x'); + late final _spine_bone_data_set_x = _spine_bone_data_set_xPtr + .asFunction(); + + double spine_bone_data_get_y( + spine_bone_data data, + ) { + return _spine_bone_data_get_y( + data, + ); + } + + late final _spine_bone_data_get_yPtr = + _lookup>( + 'spine_bone_data_get_y'); + late final _spine_bone_data_get_y = + _spine_bone_data_get_yPtr.asFunction(); + + void spine_bone_data_set_y( + spine_bone_data data, + double y, + ) { + return _spine_bone_data_set_y( + data, + y, + ); + } + + late final _spine_bone_data_set_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_y'); + late final _spine_bone_data_set_y = _spine_bone_data_set_yPtr + .asFunction(); + + double spine_bone_data_get_rotation( + spine_bone_data data, + ) { + return _spine_bone_data_get_rotation( + data, + ); + } + + late final _spine_bone_data_get_rotationPtr = + _lookup>( + 'spine_bone_data_get_rotation'); + late final _spine_bone_data_get_rotation = _spine_bone_data_get_rotationPtr + .asFunction(); + + void spine_bone_data_set_rotation( + spine_bone_data data, + double rotation, + ) { + return _spine_bone_data_set_rotation( + data, + rotation, + ); + } + + late final _spine_bone_data_set_rotationPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_rotation'); + late final _spine_bone_data_set_rotation = _spine_bone_data_set_rotationPtr + .asFunction(); + + double spine_bone_data_get_scale_x( + spine_bone_data data, + ) { + return _spine_bone_data_get_scale_x( + data, + ); + } + + late final _spine_bone_data_get_scale_xPtr = + _lookup>( + 'spine_bone_data_get_scale_x'); + late final _spine_bone_data_get_scale_x = _spine_bone_data_get_scale_xPtr + .asFunction(); + + void spine_bone_data_set_scale_x( + spine_bone_data data, + double scaleX, + ) { + return _spine_bone_data_set_scale_x( + data, + scaleX, + ); + } + + late final _spine_bone_data_set_scale_xPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_scale_x'); + late final _spine_bone_data_set_scale_x = _spine_bone_data_set_scale_xPtr + .asFunction(); + + double spine_bone_data_get_scale_y( + spine_bone_data data, + ) { + return _spine_bone_data_get_scale_y( + data, + ); + } + + late final _spine_bone_data_get_scale_yPtr = + _lookup>( + 'spine_bone_data_get_scale_y'); + late final _spine_bone_data_get_scale_y = _spine_bone_data_get_scale_yPtr + .asFunction(); + + void spine_bone_data_set_scale_y( + spine_bone_data data, + double scaleY, + ) { + return _spine_bone_data_set_scale_y( + data, + scaleY, + ); + } + + late final _spine_bone_data_set_scale_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_scale_y'); + late final _spine_bone_data_set_scale_y = _spine_bone_data_set_scale_yPtr + .asFunction(); + + double spine_bone_data_get_shear_x( + spine_bone_data data, + ) { + return _spine_bone_data_get_shear_x( + data, + ); + } + + late final _spine_bone_data_get_shear_xPtr = + _lookup>( + 'spine_bone_data_get_shear_x'); + late final _spine_bone_data_get_shear_x = _spine_bone_data_get_shear_xPtr + .asFunction(); + + void spine_bone_data_set_shear_x( + spine_bone_data data, + double shearx, + ) { + return _spine_bone_data_set_shear_x( + data, + shearx, + ); + } + + late final _spine_bone_data_set_shear_xPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_shear_x'); + late final _spine_bone_data_set_shear_x = _spine_bone_data_set_shear_xPtr + .asFunction(); + + double spine_bone_data_get_shear_y( + spine_bone_data data, + ) { + return _spine_bone_data_get_shear_y( + data, + ); + } + + late final _spine_bone_data_get_shear_yPtr = + _lookup>( + 'spine_bone_data_get_shear_y'); + late final _spine_bone_data_get_shear_y = _spine_bone_data_get_shear_yPtr + .asFunction(); + + void spine_bone_data_set_shear_y( + spine_bone_data data, + double shearY, + ) { + return _spine_bone_data_set_shear_y( + data, + shearY, + ); + } + + late final _spine_bone_data_set_shear_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_shear_y'); + late final _spine_bone_data_set_shear_y = _spine_bone_data_set_shear_yPtr + .asFunction(); + + int spine_bone_data_get_transform_mode( + spine_bone_data data, + ) { + return _spine_bone_data_get_transform_mode( + data, + ); + } + + late final _spine_bone_data_get_transform_modePtr = + _lookup>( + 'spine_bone_data_get_transform_mode'); + late final _spine_bone_data_get_transform_mode = + _spine_bone_data_get_transform_modePtr + .asFunction(); + + void spine_bone_data_set_transform_mode( + spine_bone_data data, + int mode, + ) { + return _spine_bone_data_set_transform_mode( + data, + mode, + ); + } + + late final _spine_bone_data_set_transform_modePtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_transform_mode'); + late final _spine_bone_data_set_transform_mode = + _spine_bone_data_set_transform_modePtr + .asFunction(); + + int spine_bone_data_is_skin_required( + spine_bone_data data, + ) { + return _spine_bone_data_is_skin_required( + data, + ); + } + + late final _spine_bone_data_is_skin_requiredPtr = + _lookup>( + 'spine_bone_data_is_skin_required'); + late final _spine_bone_data_is_skin_required = + _spine_bone_data_is_skin_requiredPtr + .asFunction(); + + void spine_bone_data_set_is_skin_required( + spine_bone_data data, + int isSkinRequired, + ) { + return _spine_bone_data_set_is_skin_required( + data, + isSkinRequired, + ); + } + + late final _spine_bone_data_set_is_skin_requiredPtr = _lookup< + ffi.NativeFunction>( + 'spine_bone_data_set_is_skin_required'); + late final _spine_bone_data_set_is_skin_required = + _spine_bone_data_set_is_skin_requiredPtr + .asFunction(); + + spine_color spine_bone_data_get_color( + spine_bone_data data, + ) { + return _spine_bone_data_get_color( + data, + ); + } + + late final _spine_bone_data_get_colorPtr = + _lookup>( + 'spine_bone_data_get_color'); + late final _spine_bone_data_get_color = _spine_bone_data_get_colorPtr + .asFunction(); + + void spine_bone_data_set_color( + spine_bone_data data, + double r, + double g, + double b, + double a, + ) { + return _spine_bone_data_set_color( + data, + r, + g, + b, + a, + ); + } + + late final _spine_bone_data_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_bone_data, ffi.Float, ffi.Float, ffi.Float, + ffi.Float)>>('spine_bone_data_set_color'); + late final _spine_bone_data_set_color = + _spine_bone_data_set_colorPtr.asFunction< + void Function(spine_bone_data, double, double, double, double)>(); + + void spine_bone_set_is_y_down( + int yDown, + ) { + return _spine_bone_set_is_y_down( + yDown, + ); + } + + late final _spine_bone_set_is_y_downPtr = + _lookup>( + 'spine_bone_set_is_y_down'); + late final _spine_bone_set_is_y_down = + _spine_bone_set_is_y_downPtr.asFunction(); + + int spine_bone_get_is_y_down() { + return _spine_bone_get_is_y_down(); + } + + late final _spine_bone_get_is_y_downPtr = + _lookup>( + 'spine_bone_get_is_y_down'); + late final _spine_bone_get_is_y_down = + _spine_bone_get_is_y_downPtr.asFunction(); + + void spine_bone_update( + spine_bone bone, + ) { + return _spine_bone_update( + bone, + ); + } + + late final _spine_bone_updatePtr = + _lookup>( + 'spine_bone_update'); + late final _spine_bone_update = + _spine_bone_updatePtr.asFunction(); + + void spine_bone_update_world_transform( + spine_bone bone, + ) { + return _spine_bone_update_world_transform( + bone, + ); + } + + late final _spine_bone_update_world_transformPtr = + _lookup>( + 'spine_bone_update_world_transform'); + late final _spine_bone_update_world_transform = + _spine_bone_update_world_transformPtr + .asFunction(); + + void spine_bone_update_world_transform_with( + spine_bone bone, + double x, + double y, + double rotation, + double scaleX, + double scaleY, + double shearX, + double shearY, + ) { + return _spine_bone_update_world_transform_with( + bone, + x, + y, + rotation, + scaleX, + scaleY, + shearX, + shearY, + ); + } + + late final _spine_bone_update_world_transform_withPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_bone, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float)>>('spine_bone_update_world_transform_with'); + late final _spine_bone_update_world_transform_with = + _spine_bone_update_world_transform_withPtr.asFunction< + void Function(spine_bone, double, double, double, double, double, + double, double)>(); + + void spine_bone_update_applied_transform( + spine_bone bone, + ) { + return _spine_bone_update_applied_transform( + bone, + ); + } + + late final _spine_bone_update_applied_transformPtr = + _lookup>( + 'spine_bone_update_applied_transform'); + late final _spine_bone_update_applied_transform = + _spine_bone_update_applied_transformPtr + .asFunction(); + + void spine_bone_set_to_setup_pose( + spine_bone bone, + ) { + return _spine_bone_set_to_setup_pose( + bone, + ); + } + + late final _spine_bone_set_to_setup_posePtr = + _lookup>( + 'spine_bone_set_to_setup_pose'); + late final _spine_bone_set_to_setup_pose = + _spine_bone_set_to_setup_posePtr.asFunction(); + + spine_vector spine_bone_world_to_local( + spine_bone bone, + double worldX, + double worldY, + ) { + return _spine_bone_world_to_local( + bone, + worldX, + worldY, + ); + } + + late final _spine_bone_world_to_localPtr = _lookup< + ffi.NativeFunction< + spine_vector Function( + spine_bone, ffi.Float, ffi.Float)>>('spine_bone_world_to_local'); + late final _spine_bone_world_to_local = _spine_bone_world_to_localPtr + .asFunction(); + + spine_vector spine_bone_local_to_world( + spine_bone bone, + double localX, + double localY, + ) { + return _spine_bone_local_to_world( + bone, + localX, + localY, + ); + } + + late final _spine_bone_local_to_worldPtr = _lookup< + ffi.NativeFunction< + spine_vector Function( + spine_bone, ffi.Float, ffi.Float)>>('spine_bone_local_to_world'); + late final _spine_bone_local_to_world = _spine_bone_local_to_worldPtr + .asFunction(); + + double spine_bone_world_to_local_rotation( + spine_bone bone, + double worldRotation, + ) { + return _spine_bone_world_to_local_rotation( + bone, + worldRotation, + ); + } + + late final _spine_bone_world_to_local_rotationPtr = + _lookup>( + 'spine_bone_world_to_local_rotation'); + late final _spine_bone_world_to_local_rotation = + _spine_bone_world_to_local_rotationPtr + .asFunction(); + + double spine_bone_local_to_world_rotation( + spine_bone bone, + double localRotation, + ) { + return _spine_bone_local_to_world_rotation( + bone, + localRotation, + ); + } + + late final _spine_bone_local_to_world_rotationPtr = + _lookup>( + 'spine_bone_local_to_world_rotation'); + late final _spine_bone_local_to_world_rotation = + _spine_bone_local_to_world_rotationPtr + .asFunction(); + + void spine_bone_rotate_world( + spine_bone bone, + double degrees, + ) { + return _spine_bone_rotate_world( + bone, + degrees, + ); + } + + late final _spine_bone_rotate_worldPtr = + _lookup>( + 'spine_bone_rotate_world'); + late final _spine_bone_rotate_world = _spine_bone_rotate_worldPtr + .asFunction(); + + double spine_bone_get_world_to_local_rotation_x( + spine_bone bone, + ) { + return _spine_bone_get_world_to_local_rotation_x( + bone, + ); + } + + late final _spine_bone_get_world_to_local_rotation_xPtr = + _lookup>( + 'spine_bone_get_world_to_local_rotation_x'); + late final _spine_bone_get_world_to_local_rotation_x = + _spine_bone_get_world_to_local_rotation_xPtr + .asFunction(); + + double spine_bone_get_world_to_local_rotation_y( + spine_bone bone, + ) { + return _spine_bone_get_world_to_local_rotation_y( + bone, + ); + } + + late final _spine_bone_get_world_to_local_rotation_yPtr = + _lookup>( + 'spine_bone_get_world_to_local_rotation_y'); + late final _spine_bone_get_world_to_local_rotation_y = + _spine_bone_get_world_to_local_rotation_yPtr + .asFunction(); + + spine_bone_data spine_bone_get_data( + spine_bone bone, + ) { + return _spine_bone_get_data( + bone, + ); + } + + late final _spine_bone_get_dataPtr = + _lookup>( + 'spine_bone_get_data'); + late final _spine_bone_get_data = _spine_bone_get_dataPtr + .asFunction(); + + spine_skeleton spine_bone_get_skeleton( + spine_bone bone, + ) { + return _spine_bone_get_skeleton( + bone, + ); + } + + late final _spine_bone_get_skeletonPtr = + _lookup>( + 'spine_bone_get_skeleton'); + late final _spine_bone_get_skeleton = _spine_bone_get_skeletonPtr + .asFunction(); + + spine_bone spine_bone_get_parent( + spine_bone bone, + ) { + return _spine_bone_get_parent( + bone, + ); + } + + late final _spine_bone_get_parentPtr = + _lookup>( + 'spine_bone_get_parent'); + late final _spine_bone_get_parent = + _spine_bone_get_parentPtr.asFunction(); + + int spine_bone_get_num_children( + spine_bone bone, + ) { + return _spine_bone_get_num_children( + bone, + ); + } + + late final _spine_bone_get_num_childrenPtr = + _lookup>( + 'spine_bone_get_num_children'); + late final _spine_bone_get_num_children = + _spine_bone_get_num_childrenPtr.asFunction(); + + ffi.Pointer spine_bone_get_children( + spine_bone bone, + ) { + return _spine_bone_get_children( + bone, + ); + } + + late final _spine_bone_get_childrenPtr = + _lookup Function(spine_bone)>>( + 'spine_bone_get_children'); + late final _spine_bone_get_children = _spine_bone_get_childrenPtr + .asFunction Function(spine_bone)>(); + + double spine_bone_get_x( + spine_bone bone, + ) { + return _spine_bone_get_x( + bone, + ); + } + + late final _spine_bone_get_xPtr = + _lookup>( + 'spine_bone_get_x'); + late final _spine_bone_get_x = + _spine_bone_get_xPtr.asFunction(); + + void spine_bone_set_x( + spine_bone bone, + double x, + ) { + return _spine_bone_set_x( + bone, + x, + ); + } + + late final _spine_bone_set_xPtr = + _lookup>( + 'spine_bone_set_x'); + late final _spine_bone_set_x = + _spine_bone_set_xPtr.asFunction(); + + double spine_bone_get_y( + spine_bone bone, + ) { + return _spine_bone_get_y( + bone, + ); + } + + late final _spine_bone_get_yPtr = + _lookup>( + 'spine_bone_get_y'); + late final _spine_bone_get_y = + _spine_bone_get_yPtr.asFunction(); + + void spine_bone_set_y( + spine_bone bone, + double y, + ) { + return _spine_bone_set_y( + bone, + y, + ); + } + + late final _spine_bone_set_yPtr = + _lookup>( + 'spine_bone_set_y'); + late final _spine_bone_set_y = + _spine_bone_set_yPtr.asFunction(); + + double spine_bone_get_rotation( + spine_bone bone, + ) { + return _spine_bone_get_rotation( + bone, + ); + } + + late final _spine_bone_get_rotationPtr = + _lookup>( + 'spine_bone_get_rotation'); + late final _spine_bone_get_rotation = + _spine_bone_get_rotationPtr.asFunction(); + + void spine_bone_set_rotation( + spine_bone bone, + double rotation, + ) { + return _spine_bone_set_rotation( + bone, + rotation, + ); + } + + late final _spine_bone_set_rotationPtr = + _lookup>( + 'spine_bone_set_rotation'); + late final _spine_bone_set_rotation = _spine_bone_set_rotationPtr + .asFunction(); + + double spine_bone_get_scale_x( + spine_bone bone, + ) { + return _spine_bone_get_scale_x( + bone, + ); + } + + late final _spine_bone_get_scale_xPtr = + _lookup>( + 'spine_bone_get_scale_x'); + late final _spine_bone_get_scale_x = + _spine_bone_get_scale_xPtr.asFunction(); + + void spine_bone_set_scale_x( + spine_bone bone, + double scaleX, + ) { + return _spine_bone_set_scale_x( + bone, + scaleX, + ); + } + + late final _spine_bone_set_scale_xPtr = + _lookup>( + 'spine_bone_set_scale_x'); + late final _spine_bone_set_scale_x = _spine_bone_set_scale_xPtr + .asFunction(); + + double spine_bone_get_scale_y( + spine_bone bone, + ) { + return _spine_bone_get_scale_y( + bone, + ); + } + + late final _spine_bone_get_scale_yPtr = + _lookup>( + 'spine_bone_get_scale_y'); + late final _spine_bone_get_scale_y = + _spine_bone_get_scale_yPtr.asFunction(); + + void spine_bone_set_scale_y( + spine_bone bone, + double scaleY, + ) { + return _spine_bone_set_scale_y( + bone, + scaleY, + ); + } + + late final _spine_bone_set_scale_yPtr = + _lookup>( + 'spine_bone_set_scale_y'); + late final _spine_bone_set_scale_y = _spine_bone_set_scale_yPtr + .asFunction(); + + double spine_bone_get_shear_x( + spine_bone bone, + ) { + return _spine_bone_get_shear_x( + bone, + ); + } + + late final _spine_bone_get_shear_xPtr = + _lookup>( + 'spine_bone_get_shear_x'); + late final _spine_bone_get_shear_x = + _spine_bone_get_shear_xPtr.asFunction(); + + void spine_bone_set_shear_x( + spine_bone bone, + double shearX, + ) { + return _spine_bone_set_shear_x( + bone, + shearX, + ); + } + + late final _spine_bone_set_shear_xPtr = + _lookup>( + 'spine_bone_set_shear_x'); + late final _spine_bone_set_shear_x = _spine_bone_set_shear_xPtr + .asFunction(); + + double spine_bone_get_shear_y( + spine_bone bone, + ) { + return _spine_bone_get_shear_y( + bone, + ); + } + + late final _spine_bone_get_shear_yPtr = + _lookup>( + 'spine_bone_get_shear_y'); + late final _spine_bone_get_shear_y = + _spine_bone_get_shear_yPtr.asFunction(); + + void spine_bone_set_shear_y( + spine_bone bone, + double shearY, + ) { + return _spine_bone_set_shear_y( + bone, + shearY, + ); + } + + late final _spine_bone_set_shear_yPtr = + _lookup>( + 'spine_bone_set_shear_y'); + late final _spine_bone_set_shear_y = _spine_bone_set_shear_yPtr + .asFunction(); + + double spine_bone_get_applied_rotation( + spine_bone bone, + ) { + return _spine_bone_get_applied_rotation( + bone, + ); + } + + late final _spine_bone_get_applied_rotationPtr = + _lookup>( + 'spine_bone_get_applied_rotation'); + late final _spine_bone_get_applied_rotation = + _spine_bone_get_applied_rotationPtr + .asFunction(); + + void spine_bone_set_applied_rotation( + spine_bone bone, + double rotation, + ) { + return _spine_bone_set_applied_rotation( + bone, + rotation, + ); + } + + late final _spine_bone_set_applied_rotationPtr = + _lookup>( + 'spine_bone_set_applied_rotation'); + late final _spine_bone_set_applied_rotation = + _spine_bone_set_applied_rotationPtr + .asFunction(); + + double spine_bone_get_a_x( + spine_bone bone, + ) { + return _spine_bone_get_a_x( + bone, + ); + } + + late final _spine_bone_get_a_xPtr = + _lookup>( + 'spine_bone_get_a_x'); + late final _spine_bone_get_a_x = + _spine_bone_get_a_xPtr.asFunction(); + + void spine_bone_set_a_x( + spine_bone bone, + double x, + ) { + return _spine_bone_set_a_x( + bone, + x, + ); + } + + late final _spine_bone_set_a_xPtr = + _lookup>( + 'spine_bone_set_a_x'); + late final _spine_bone_set_a_x = + _spine_bone_set_a_xPtr.asFunction(); + + double spine_bone_get_a_y( + spine_bone bone, + ) { + return _spine_bone_get_a_y( + bone, + ); + } + + late final _spine_bone_get_a_yPtr = + _lookup>( + 'spine_bone_get_a_y'); + late final _spine_bone_get_a_y = + _spine_bone_get_a_yPtr.asFunction(); + + void spine_bone_set_a_y( + spine_bone bone, + double y, + ) { + return _spine_bone_set_a_y( + bone, + y, + ); + } + + late final _spine_bone_set_a_yPtr = + _lookup>( + 'spine_bone_set_a_y'); + late final _spine_bone_set_a_y = + _spine_bone_set_a_yPtr.asFunction(); + + double spine_bone_get_a_scale_x( + spine_bone bone, + ) { + return _spine_bone_get_a_scale_x( + bone, + ); + } + + late final _spine_bone_get_a_scale_xPtr = + _lookup>( + 'spine_bone_get_a_scale_x'); + late final _spine_bone_get_a_scale_x = + _spine_bone_get_a_scale_xPtr.asFunction(); + + void spine_bone_set_a_scale_x( + spine_bone bone, + double scaleX, + ) { + return _spine_bone_set_a_scale_x( + bone, + scaleX, + ); + } + + late final _spine_bone_set_a_scale_xPtr = + _lookup>( + 'spine_bone_set_a_scale_x'); + late final _spine_bone_set_a_scale_x = _spine_bone_set_a_scale_xPtr + .asFunction(); + + double spine_bone_get_a_scale_y( + spine_bone bone, + ) { + return _spine_bone_get_a_scale_y( + bone, + ); + } + + late final _spine_bone_get_a_scale_yPtr = + _lookup>( + 'spine_bone_get_a_scale_y'); + late final _spine_bone_get_a_scale_y = + _spine_bone_get_a_scale_yPtr.asFunction(); + + void spine_bone_set_a_scale_y( + spine_bone bone, + double scaleY, + ) { + return _spine_bone_set_a_scale_y( + bone, + scaleY, + ); + } + + late final _spine_bone_set_a_scale_yPtr = + _lookup>( + 'spine_bone_set_a_scale_y'); + late final _spine_bone_set_a_scale_y = _spine_bone_set_a_scale_yPtr + .asFunction(); + + double spine_bone_get_a_shear_x( + spine_bone bone, + ) { + return _spine_bone_get_a_shear_x( + bone, + ); + } + + late final _spine_bone_get_a_shear_xPtr = + _lookup>( + 'spine_bone_get_a_shear_x'); + late final _spine_bone_get_a_shear_x = + _spine_bone_get_a_shear_xPtr.asFunction(); + + void spine_bone_set_a_shear_x( + spine_bone bone, + double shearX, + ) { + return _spine_bone_set_a_shear_x( + bone, + shearX, + ); + } + + late final _spine_bone_set_a_shear_xPtr = + _lookup>( + 'spine_bone_set_a_shear_x'); + late final _spine_bone_set_a_shear_x = _spine_bone_set_a_shear_xPtr + .asFunction(); + + double spine_bone_get_a_shear_y( + spine_bone bone, + ) { + return _spine_bone_get_a_shear_y( + bone, + ); + } + + late final _spine_bone_get_a_shear_yPtr = + _lookup>( + 'spine_bone_get_a_shear_y'); + late final _spine_bone_get_a_shear_y = + _spine_bone_get_a_shear_yPtr.asFunction(); + + void spine_bone_set_a_shear_y( + spine_bone bone, + double shearY, + ) { + return _spine_bone_set_a_shear_y( + bone, + shearY, + ); + } + + late final _spine_bone_set_a_shear_yPtr = + _lookup>( + 'spine_bone_set_a_shear_y'); + late final _spine_bone_set_a_shear_y = _spine_bone_set_a_shear_yPtr + .asFunction(); + + double spine_bone_get_a( + spine_bone bone, + ) { + return _spine_bone_get_a( + bone, + ); + } + + late final _spine_bone_get_aPtr = + _lookup>( + 'spine_bone_get_a'); + late final _spine_bone_get_a = + _spine_bone_get_aPtr.asFunction(); + + void spine_bone_set_a( + spine_bone bone, + double a, + ) { + return _spine_bone_set_a( + bone, + a, + ); + } + + late final _spine_bone_set_aPtr = + _lookup>( + 'spine_bone_set_a'); + late final _spine_bone_set_a = + _spine_bone_set_aPtr.asFunction(); + + double spine_bone_get_b( + spine_bone bone, + ) { + return _spine_bone_get_b( + bone, + ); + } + + late final _spine_bone_get_bPtr = + _lookup>( + 'spine_bone_get_b'); + late final _spine_bone_get_b = + _spine_bone_get_bPtr.asFunction(); + + void spine_bone_set_b( + spine_bone bone, + double b, + ) { + return _spine_bone_set_b( + bone, + b, + ); + } + + late final _spine_bone_set_bPtr = + _lookup>( + 'spine_bone_set_b'); + late final _spine_bone_set_b = + _spine_bone_set_bPtr.asFunction(); + + double spine_bone_get_c( + spine_bone bone, + ) { + return _spine_bone_get_c( + bone, + ); + } + + late final _spine_bone_get_cPtr = + _lookup>( + 'spine_bone_get_c'); + late final _spine_bone_get_c = + _spine_bone_get_cPtr.asFunction(); + + void spine_bone_set_c( + spine_bone bone, + double c, + ) { + return _spine_bone_set_c( + bone, + c, + ); + } + + late final _spine_bone_set_cPtr = + _lookup>( + 'spine_bone_set_c'); + late final _spine_bone_set_c = + _spine_bone_set_cPtr.asFunction(); + + double spine_bone_get_d( + spine_bone bone, + ) { + return _spine_bone_get_d( + bone, + ); + } + + late final _spine_bone_get_dPtr = + _lookup>( + 'spine_bone_get_d'); + late final _spine_bone_get_d = + _spine_bone_get_dPtr.asFunction(); + + void spine_bone_set_d( + spine_bone bone, + double d, + ) { + return _spine_bone_set_d( + bone, + d, + ); + } + + late final _spine_bone_set_dPtr = + _lookup>( + 'spine_bone_set_d'); + late final _spine_bone_set_d = + _spine_bone_set_dPtr.asFunction(); + + double spine_bone_get_world_x( + spine_bone bone, + ) { + return _spine_bone_get_world_x( + bone, + ); + } + + late final _spine_bone_get_world_xPtr = + _lookup>( + 'spine_bone_get_world_x'); + late final _spine_bone_get_world_x = + _spine_bone_get_world_xPtr.asFunction(); + + void spine_bone_set_world_x( + spine_bone bone, + double worldX, + ) { + return _spine_bone_set_world_x( + bone, + worldX, + ); + } + + late final _spine_bone_set_world_xPtr = + _lookup>( + 'spine_bone_set_world_x'); + late final _spine_bone_set_world_x = _spine_bone_set_world_xPtr + .asFunction(); + + double spine_bone_get_world_y( + spine_bone bone, + ) { + return _spine_bone_get_world_y( + bone, + ); + } + + late final _spine_bone_get_world_yPtr = + _lookup>( + 'spine_bone_get_world_y'); + late final _spine_bone_get_world_y = + _spine_bone_get_world_yPtr.asFunction(); + + void spine_bone_set_world_y( + spine_bone bone, + double worldY, + ) { + return _spine_bone_set_world_y( + bone, + worldY, + ); + } + + late final _spine_bone_set_world_yPtr = + _lookup>( + 'spine_bone_set_world_y'); + late final _spine_bone_set_world_y = _spine_bone_set_world_yPtr + .asFunction(); + + double spine_bone_get_world_rotation_x( + spine_bone bone, + ) { + return _spine_bone_get_world_rotation_x( + bone, + ); + } + + late final _spine_bone_get_world_rotation_xPtr = + _lookup>( + 'spine_bone_get_world_rotation_x'); + late final _spine_bone_get_world_rotation_x = + _spine_bone_get_world_rotation_xPtr + .asFunction(); + + double spine_bone_get_world_rotation_y( + spine_bone bone, + ) { + return _spine_bone_get_world_rotation_y( + bone, + ); + } + + late final _spine_bone_get_world_rotation_yPtr = + _lookup>( + 'spine_bone_get_world_rotation_y'); + late final _spine_bone_get_world_rotation_y = + _spine_bone_get_world_rotation_yPtr + .asFunction(); + + double spine_bone_get_world_scale_x( + spine_bone bone, + ) { + return _spine_bone_get_world_scale_x( + bone, + ); + } + + late final _spine_bone_get_world_scale_xPtr = + _lookup>( + 'spine_bone_get_world_scale_x'); + late final _spine_bone_get_world_scale_x = _spine_bone_get_world_scale_xPtr + .asFunction(); + + double spine_bone_get_world_scale_y( + spine_bone bone, + ) { + return _spine_bone_get_world_scale_y( + bone, + ); + } + + late final _spine_bone_get_world_scale_yPtr = + _lookup>( + 'spine_bone_get_world_scale_y'); + late final _spine_bone_get_world_scale_y = _spine_bone_get_world_scale_yPtr + .asFunction(); + + int spine_bone_get_is_active( + spine_bone bone, + ) { + return _spine_bone_get_is_active( + bone, + ); + } + + late final _spine_bone_get_is_activePtr = + _lookup>( + 'spine_bone_get_is_active'); + late final _spine_bone_get_is_active = + _spine_bone_get_is_activePtr.asFunction(); + + void spine_bone_set_is_active( + spine_bone bone, + int isActive, + ) { + return _spine_bone_set_is_active( + bone, + isActive, + ); + } + + late final _spine_bone_set_is_activePtr = + _lookup>( + 'spine_bone_set_is_active'); + late final _spine_bone_set_is_active = + _spine_bone_set_is_activePtr.asFunction(); + + ffi.Pointer spine_attachment_get_name( + spine_attachment attachment, + ) { + return _spine_attachment_get_name( + attachment, + ); + } + + late final _spine_attachment_get_namePtr = + _lookup Function(spine_attachment)>>( + 'spine_attachment_get_name'); + late final _spine_attachment_get_name = _spine_attachment_get_namePtr + .asFunction Function(spine_attachment)>(); + + int spine_attachment_get_type( + spine_attachment attachment, + ) { + return _spine_attachment_get_type( + attachment, + ); + } + + late final _spine_attachment_get_typePtr = + _lookup>( + 'spine_attachment_get_type'); + late final _spine_attachment_get_type = _spine_attachment_get_typePtr + .asFunction(); + + spine_attachment spine_attachment_copy( + spine_attachment attachment, + ) { + return _spine_attachment_copy( + attachment, + ); + } + + late final _spine_attachment_copyPtr = + _lookup>( + 'spine_attachment_copy'); + late final _spine_attachment_copy = _spine_attachment_copyPtr + .asFunction(); + + void spine_attachment_dispose( + spine_attachment attachment, + ) { + return _spine_attachment_dispose( + attachment, + ); + } + + late final _spine_attachment_disposePtr = + _lookup>( + 'spine_attachment_dispose'); + late final _spine_attachment_dispose = _spine_attachment_disposePtr + .asFunction(); + + spine_vector spine_point_attachment_compute_world_position( + spine_point_attachment attachment, + spine_bone bone, + ) { + return _spine_point_attachment_compute_world_position( + attachment, + bone, + ); + } + + late final _spine_point_attachment_compute_world_positionPtr = _lookup< + ffi.NativeFunction< + spine_vector Function(spine_point_attachment, + spine_bone)>>('spine_point_attachment_compute_world_position'); + late final _spine_point_attachment_compute_world_position = + _spine_point_attachment_compute_world_positionPtr.asFunction< + spine_vector Function(spine_point_attachment, spine_bone)>(); + + double spine_point_attachment_compute_world_rotation( + spine_point_attachment attachment, + spine_bone bone, + ) { + return _spine_point_attachment_compute_world_rotation( + attachment, + bone, + ); + } + + late final _spine_point_attachment_compute_world_rotationPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_point_attachment, + spine_bone)>>('spine_point_attachment_compute_world_rotation'); + late final _spine_point_attachment_compute_world_rotation = + _spine_point_attachment_compute_world_rotationPtr + .asFunction(); + + double spine_point_attachment_get_x( + spine_point_attachment attachment, + ) { + return _spine_point_attachment_get_x( + attachment, + ); + } + + late final _spine_point_attachment_get_xPtr = + _lookup>( + 'spine_point_attachment_get_x'); + late final _spine_point_attachment_get_x = _spine_point_attachment_get_xPtr + .asFunction(); + + void spine_point_attachment_set_x( + spine_point_attachment attachment, + double x, + ) { + return _spine_point_attachment_set_x( + attachment, + x, + ); + } + + late final _spine_point_attachment_set_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_point_attachment, + ffi.Float)>>('spine_point_attachment_set_x'); + late final _spine_point_attachment_set_x = _spine_point_attachment_set_xPtr + .asFunction(); + + double spine_point_attachment_get_y( + spine_point_attachment attachment, + ) { + return _spine_point_attachment_get_y( + attachment, + ); + } + + late final _spine_point_attachment_get_yPtr = + _lookup>( + 'spine_point_attachment_get_y'); + late final _spine_point_attachment_get_y = _spine_point_attachment_get_yPtr + .asFunction(); + + void spine_point_attachment_set_y( + spine_point_attachment attachment, + double y, + ) { + return _spine_point_attachment_set_y( + attachment, + y, + ); + } + + late final _spine_point_attachment_set_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_point_attachment, + ffi.Float)>>('spine_point_attachment_set_y'); + late final _spine_point_attachment_set_y = _spine_point_attachment_set_yPtr + .asFunction(); + + double spine_point_attachment_get_rotation( + spine_point_attachment attachment, + ) { + return _spine_point_attachment_get_rotation( + attachment, + ); + } + + late final _spine_point_attachment_get_rotationPtr = + _lookup>( + 'spine_point_attachment_get_rotation'); + late final _spine_point_attachment_get_rotation = + _spine_point_attachment_get_rotationPtr + .asFunction(); + + void spine_point_attachment_set_rotation( + spine_point_attachment attachment, + double rotation, + ) { + return _spine_point_attachment_set_rotation( + attachment, + rotation, + ); + } + + late final _spine_point_attachment_set_rotationPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_point_attachment, + ffi.Float)>>('spine_point_attachment_set_rotation'); + late final _spine_point_attachment_set_rotation = + _spine_point_attachment_set_rotationPtr + .asFunction(); + + spine_color spine_point_attachment_get_color( + spine_point_attachment attachment, + ) { + return _spine_point_attachment_get_color( + attachment, + ); + } + + late final _spine_point_attachment_get_colorPtr = + _lookup>( + 'spine_point_attachment_get_color'); + late final _spine_point_attachment_get_color = + _spine_point_attachment_get_colorPtr + .asFunction(); + + void spine_point_attachment_set_color( + spine_point_attachment attachment, + double r, + double g, + double b, + double a, + ) { + return _spine_point_attachment_set_color( + attachment, + r, + g, + b, + a, + ); + } + + late final _spine_point_attachment_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_point_attachment, ffi.Float, ffi.Float, + ffi.Float, ffi.Float)>>('spine_point_attachment_set_color'); + late final _spine_point_attachment_set_color = + _spine_point_attachment_set_colorPtr.asFunction< + void Function( + spine_point_attachment, double, double, double, double)>(); + + void spine_region_attachment_update_region( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_update_region( + attachment, + ); + } + + late final _spine_region_attachment_update_regionPtr = + _lookup>( + 'spine_region_attachment_update_region'); + late final _spine_region_attachment_update_region = + _spine_region_attachment_update_regionPtr + .asFunction(); + + void spine_region_attachment_compute_world_vertices( + spine_region_attachment attachment, + spine_slot slot, + ffi.Pointer worldVertices, + ) { + return _spine_region_attachment_compute_world_vertices( + attachment, + slot, + worldVertices, + ); + } + + late final _spine_region_attachment_compute_world_verticesPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, spine_slot, + ffi.Pointer)>>( + 'spine_region_attachment_compute_world_vertices'); + late final _spine_region_attachment_compute_world_vertices = + _spine_region_attachment_compute_world_verticesPtr.asFunction< + void Function( + spine_region_attachment, spine_slot, ffi.Pointer)>(); + + double spine_region_attachment_get_x( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_x( + attachment, + ); + } + + late final _spine_region_attachment_get_xPtr = + _lookup>( + 'spine_region_attachment_get_x'); + late final _spine_region_attachment_get_x = _spine_region_attachment_get_xPtr + .asFunction(); + + void spine_region_attachment_set_x( + spine_region_attachment attachment, + double x, + ) { + return _spine_region_attachment_set_x( + attachment, + x, + ); + } + + late final _spine_region_attachment_set_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_x'); + late final _spine_region_attachment_set_x = _spine_region_attachment_set_xPtr + .asFunction(); + + double spine_region_attachment_get_y( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_y( + attachment, + ); + } + + late final _spine_region_attachment_get_yPtr = + _lookup>( + 'spine_region_attachment_get_y'); + late final _spine_region_attachment_get_y = _spine_region_attachment_get_yPtr + .asFunction(); + + void spine_region_attachment_set_y( + spine_region_attachment attachment, + double y, + ) { + return _spine_region_attachment_set_y( + attachment, + y, + ); + } + + late final _spine_region_attachment_set_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_y'); + late final _spine_region_attachment_set_y = _spine_region_attachment_set_yPtr + .asFunction(); + + double spine_region_attachment_get_rotation( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_rotation( + attachment, + ); + } + + late final _spine_region_attachment_get_rotationPtr = + _lookup>( + 'spine_region_attachment_get_rotation'); + late final _spine_region_attachment_get_rotation = + _spine_region_attachment_get_rotationPtr + .asFunction(); + + void spine_region_attachment_set_rotation( + spine_region_attachment attachment, + double rotation, + ) { + return _spine_region_attachment_set_rotation( + attachment, + rotation, + ); + } + + late final _spine_region_attachment_set_rotationPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_rotation'); + late final _spine_region_attachment_set_rotation = + _spine_region_attachment_set_rotationPtr + .asFunction(); + + double spine_region_attachment_get_scale_x( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_scale_x( + attachment, + ); + } + + late final _spine_region_attachment_get_scale_xPtr = + _lookup>( + 'spine_region_attachment_get_scale_x'); + late final _spine_region_attachment_get_scale_x = + _spine_region_attachment_get_scale_xPtr + .asFunction(); + + void spine_region_attachment_set_scale_x( + spine_region_attachment attachment, + double scaleX, + ) { + return _spine_region_attachment_set_scale_x( + attachment, + scaleX, + ); + } + + late final _spine_region_attachment_set_scale_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_scale_x'); + late final _spine_region_attachment_set_scale_x = + _spine_region_attachment_set_scale_xPtr + .asFunction(); + + double spine_region_attachment_get_scale_y( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_scale_y( + attachment, + ); + } + + late final _spine_region_attachment_get_scale_yPtr = + _lookup>( + 'spine_region_attachment_get_scale_y'); + late final _spine_region_attachment_get_scale_y = + _spine_region_attachment_get_scale_yPtr + .asFunction(); + + void spine_region_attachment_set_scale_y( + spine_region_attachment attachment, + double scaleY, + ) { + return _spine_region_attachment_set_scale_y( + attachment, + scaleY, + ); + } + + late final _spine_region_attachment_set_scale_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_scale_y'); + late final _spine_region_attachment_set_scale_y = + _spine_region_attachment_set_scale_yPtr + .asFunction(); + + double spine_region_attachment_get_width( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_width( + attachment, + ); + } + + late final _spine_region_attachment_get_widthPtr = + _lookup>( + 'spine_region_attachment_get_width'); + late final _spine_region_attachment_get_width = + _spine_region_attachment_get_widthPtr + .asFunction(); + + void spine_region_attachment_set_width( + spine_region_attachment attachment, + double width, + ) { + return _spine_region_attachment_set_width( + attachment, + width, + ); + } + + late final _spine_region_attachment_set_widthPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_width'); + late final _spine_region_attachment_set_width = + _spine_region_attachment_set_widthPtr + .asFunction(); + + double spine_region_attachment_get_height( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_height( + attachment, + ); + } + + late final _spine_region_attachment_get_heightPtr = + _lookup>( + 'spine_region_attachment_get_height'); + late final _spine_region_attachment_get_height = + _spine_region_attachment_get_heightPtr + .asFunction(); + + void spine_region_attachment_set_height( + spine_region_attachment attachment, + double height, + ) { + return _spine_region_attachment_set_height( + attachment, + height, + ); + } + + late final _spine_region_attachment_set_heightPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, + ffi.Float)>>('spine_region_attachment_set_height'); + late final _spine_region_attachment_set_height = + _spine_region_attachment_set_heightPtr + .asFunction(); + + spine_color spine_region_attachment_get_color( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_color( + attachment, + ); + } + + late final _spine_region_attachment_get_colorPtr = _lookup< + ffi.NativeFunction>( + 'spine_region_attachment_get_color'); + late final _spine_region_attachment_get_color = + _spine_region_attachment_get_colorPtr + .asFunction(); + + void spine_region_attachment_set_color( + spine_region_attachment attachment, + double r, + double g, + double b, + double a, + ) { + return _spine_region_attachment_set_color( + attachment, + r, + g, + b, + a, + ); + } + + late final _spine_region_attachment_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_region_attachment, ffi.Float, ffi.Float, + ffi.Float, ffi.Float)>>('spine_region_attachment_set_color'); + late final _spine_region_attachment_set_color = + _spine_region_attachment_set_colorPtr.asFunction< + void Function( + spine_region_attachment, double, double, double, double)>(); + + ffi.Pointer spine_region_attachment_get_path( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_path( + attachment, + ); + } + + late final _spine_region_attachment_get_pathPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_region_attachment)>>('spine_region_attachment_get_path'); + late final _spine_region_attachment_get_path = + _spine_region_attachment_get_pathPtr + .asFunction Function(spine_region_attachment)>(); + + /// OMITTED setPath() + spine_texture_region spine_region_attachment_get_region( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_region( + attachment, + ); + } + + late final _spine_region_attachment_get_regionPtr = _lookup< + ffi.NativeFunction< + spine_texture_region Function( + spine_region_attachment)>>('spine_region_attachment_get_region'); + late final _spine_region_attachment_get_region = + _spine_region_attachment_get_regionPtr + .asFunction(); + + /// OMITTED setRegion() + spine_sequence spine_region_attachment_get_sequence( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_sequence( + attachment, + ); + } + + late final _spine_region_attachment_get_sequencePtr = _lookup< + ffi.NativeFunction>( + 'spine_region_attachment_get_sequence'); + late final _spine_region_attachment_get_sequence = + _spine_region_attachment_get_sequencePtr + .asFunction(); + + /// OMITTED setSequence() + int spine_region_attachment_get_num_offset( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_num_offset( + attachment, + ); + } + + late final _spine_region_attachment_get_num_offsetPtr = + _lookup>( + 'spine_region_attachment_get_num_offset'); + late final _spine_region_attachment_get_num_offset = + _spine_region_attachment_get_num_offsetPtr + .asFunction(); + + ffi.Pointer spine_region_attachment_get_offset( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_offset( + attachment, + ); + } + + late final _spine_region_attachment_get_offsetPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_region_attachment)>>('spine_region_attachment_get_offset'); + late final _spine_region_attachment_get_offset = + _spine_region_attachment_get_offsetPtr.asFunction< + ffi.Pointer Function(spine_region_attachment)>(); + + int spine_region_attachment_get_num_uvs( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_num_uvs( + attachment, + ); + } + + late final _spine_region_attachment_get_num_uvsPtr = + _lookup>( + 'spine_region_attachment_get_num_uvs'); + late final _spine_region_attachment_get_num_uvs = + _spine_region_attachment_get_num_uvsPtr + .asFunction(); + + ffi.Pointer spine_region_attachment_get_uvs( + spine_region_attachment attachment, + ) { + return _spine_region_attachment_get_uvs( + attachment, + ); + } + + late final _spine_region_attachment_get_uvsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_region_attachment)>>('spine_region_attachment_get_uvs'); + late final _spine_region_attachment_get_uvs = + _spine_region_attachment_get_uvsPtr.asFunction< + ffi.Pointer Function(spine_region_attachment)>(); + + int spine_vertex_attachment_get_world_vertices_length( + spine_vertex_attachment attachment, + ) { + return _spine_vertex_attachment_get_world_vertices_length( + attachment, + ); + } + + late final _spine_vertex_attachment_get_world_vertices_lengthPtr = + _lookup>( + 'spine_vertex_attachment_get_world_vertices_length'); + late final _spine_vertex_attachment_get_world_vertices_length = + _spine_vertex_attachment_get_world_vertices_lengthPtr + .asFunction(); + + void spine_vertex_attachment_compute_world_vertices( + spine_vertex_attachment attachment, + spine_slot slot, + ffi.Pointer worldVertices, + ) { + return _spine_vertex_attachment_compute_world_vertices( + attachment, + slot, + worldVertices, + ); + } + + late final _spine_vertex_attachment_compute_world_verticesPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_vertex_attachment, spine_slot, + ffi.Pointer)>>( + 'spine_vertex_attachment_compute_world_vertices'); + late final _spine_vertex_attachment_compute_world_vertices = + _spine_vertex_attachment_compute_world_verticesPtr.asFunction< + void Function( + spine_vertex_attachment, spine_slot, ffi.Pointer)>(); + + /// OMITTED getId() + int spine_vertex_attachment_get_num_bones( + spine_vertex_attachment attachment, + ) { + return _spine_vertex_attachment_get_num_bones( + attachment, + ); + } + + late final _spine_vertex_attachment_get_num_bonesPtr = + _lookup>( + 'spine_vertex_attachment_get_num_bones'); + late final _spine_vertex_attachment_get_num_bones = + _spine_vertex_attachment_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_vertex_attachment_get_bones( + spine_vertex_attachment attachment, + ) { + return _spine_vertex_attachment_get_bones( + attachment, + ); + } + + late final _spine_vertex_attachment_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_vertex_attachment)>>('spine_vertex_attachment_get_bones'); + late final _spine_vertex_attachment_get_bones = + _spine_vertex_attachment_get_bonesPtr.asFunction< + ffi.Pointer Function(spine_vertex_attachment)>(); + + int spine_vertex_attachment_get_num_vertices( + spine_vertex_attachment attachment, + ) { + return _spine_vertex_attachment_get_num_vertices( + attachment, + ); + } + + late final _spine_vertex_attachment_get_num_verticesPtr = + _lookup>( + 'spine_vertex_attachment_get_num_vertices'); + late final _spine_vertex_attachment_get_num_vertices = + _spine_vertex_attachment_get_num_verticesPtr + .asFunction(); + + ffi.Pointer spine_vertex_attachment_get_vertices( + spine_vertex_attachment attachment, + ) { + return _spine_vertex_attachment_get_vertices( + attachment, + ); + } + + late final _spine_vertex_attachment_get_verticesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function(spine_vertex_attachment)>>( + 'spine_vertex_attachment_get_vertices'); + late final _spine_vertex_attachment_get_vertices = + _spine_vertex_attachment_get_verticesPtr.asFunction< + ffi.Pointer Function(spine_vertex_attachment)>(); + + spine_attachment spine_vertex_attachment_get_timeline_attachment( + spine_vertex_attachment timelineAttachment, + ) { + return _spine_vertex_attachment_get_timeline_attachment( + timelineAttachment, + ); + } + + late final _spine_vertex_attachment_get_timeline_attachmentPtr = _lookup< + ffi.NativeFunction< + spine_attachment Function(spine_vertex_attachment)>>( + 'spine_vertex_attachment_get_timeline_attachment'); + late final _spine_vertex_attachment_get_timeline_attachment = + _spine_vertex_attachment_get_timeline_attachmentPtr + .asFunction(); + + void spine_vertex_attachment_set_timeline_attachment( + spine_vertex_attachment attachment, + spine_attachment timelineAttachment, + ) { + return _spine_vertex_attachment_set_timeline_attachment( + attachment, + timelineAttachment, + ); + } + + late final _spine_vertex_attachment_set_timeline_attachmentPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_vertex_attachment, spine_attachment)>>( + 'spine_vertex_attachment_set_timeline_attachment'); + late final _spine_vertex_attachment_set_timeline_attachment = + _spine_vertex_attachment_set_timeline_attachmentPtr.asFunction< + void Function(spine_vertex_attachment, spine_attachment)>(); + + /// OMITTED copyTo() + void spine_mesh_attachment_update_region( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_update_region( + attachment, + ); + } + + late final _spine_mesh_attachment_update_regionPtr = + _lookup>( + 'spine_mesh_attachment_update_region'); + late final _spine_mesh_attachment_update_region = + _spine_mesh_attachment_update_regionPtr + .asFunction(); + + int spine_mesh_attachment_get_hull_length( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_hull_length( + attachment, + ); + } + + late final _spine_mesh_attachment_get_hull_lengthPtr = + _lookup>( + 'spine_mesh_attachment_get_hull_length'); + late final _spine_mesh_attachment_get_hull_length = + _spine_mesh_attachment_get_hull_lengthPtr + .asFunction(); + + void spine_mesh_attachment_set_hull_length( + spine_mesh_attachment attachment, + int hullLength, + ) { + return _spine_mesh_attachment_set_hull_length( + attachment, + hullLength, + ); + } + + late final _spine_mesh_attachment_set_hull_lengthPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_mesh_attachment, + ffi.Int32)>>('spine_mesh_attachment_set_hull_length'); + late final _spine_mesh_attachment_set_hull_length = + _spine_mesh_attachment_set_hull_lengthPtr + .asFunction(); + + int spine_mesh_attachment_get_num_region_uvs( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_num_region_uvs( + attachment, + ); + } + + late final _spine_mesh_attachment_get_num_region_uvsPtr = + _lookup>( + 'spine_mesh_attachment_get_num_region_uvs'); + late final _spine_mesh_attachment_get_num_region_uvs = + _spine_mesh_attachment_get_num_region_uvsPtr + .asFunction(); + + ffi.Pointer spine_mesh_attachment_get_region_uvs( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_region_uvs( + attachment, + ); + } + + late final _spine_mesh_attachment_get_region_uvsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_region_uvs'); + late final _spine_mesh_attachment_get_region_uvs = + _spine_mesh_attachment_get_region_uvsPtr + .asFunction Function(spine_mesh_attachment)>(); + + int spine_mesh_attachment_get_num_uvs( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_num_uvs( + attachment, + ); + } + + late final _spine_mesh_attachment_get_num_uvsPtr = + _lookup>( + 'spine_mesh_attachment_get_num_uvs'); + late final _spine_mesh_attachment_get_num_uvs = + _spine_mesh_attachment_get_num_uvsPtr + .asFunction(); + + ffi.Pointer spine_mesh_attachment_get_uvs( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_uvs( + attachment, + ); + } + + late final _spine_mesh_attachment_get_uvsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_uvs'); + late final _spine_mesh_attachment_get_uvs = _spine_mesh_attachment_get_uvsPtr + .asFunction Function(spine_mesh_attachment)>(); + + int spine_mesh_attachment_get_num_triangles( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_num_triangles( + attachment, + ); + } + + late final _spine_mesh_attachment_get_num_trianglesPtr = + _lookup>( + 'spine_mesh_attachment_get_num_triangles'); + late final _spine_mesh_attachment_get_num_triangles = + _spine_mesh_attachment_get_num_trianglesPtr + .asFunction(); + + ffi.Pointer spine_mesh_attachment_get_triangles( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_triangles( + attachment, + ); + } + + late final _spine_mesh_attachment_get_trianglesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_triangles'); + late final _spine_mesh_attachment_get_triangles = + _spine_mesh_attachment_get_trianglesPtr.asFunction< + ffi.Pointer Function(spine_mesh_attachment)>(); + + spine_color spine_mesh_attachment_get_color( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_color( + attachment, + ); + } + + late final _spine_mesh_attachment_get_colorPtr = + _lookup>( + 'spine_mesh_attachment_get_color'); + late final _spine_mesh_attachment_get_color = + _spine_mesh_attachment_get_colorPtr + .asFunction(); + + void spine_mesh_attachment_set_color( + spine_mesh_attachment attachment, + double r, + double g, + double b, + double a, + ) { + return _spine_mesh_attachment_set_color( + attachment, + r, + g, + b, + a, + ); + } + + late final _spine_mesh_attachment_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_mesh_attachment, ffi.Float, ffi.Float, + ffi.Float, ffi.Float)>>('spine_mesh_attachment_set_color'); + late final _spine_mesh_attachment_set_color = + _spine_mesh_attachment_set_colorPtr.asFunction< + void Function( + spine_mesh_attachment, double, double, double, double)>(); + + ffi.Pointer spine_mesh_attachment_get_path( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_path( + attachment, + ); + } + + late final _spine_mesh_attachment_get_pathPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_path'); + late final _spine_mesh_attachment_get_path = + _spine_mesh_attachment_get_pathPtr + .asFunction Function(spine_mesh_attachment)>(); + + /// OMITTED setPath() + spine_texture_region spine_mesh_attachment_get_region( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_region( + attachment, + ); + } + + late final _spine_mesh_attachment_get_regionPtr = _lookup< + ffi.NativeFunction< + spine_texture_region Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_region'); + late final _spine_mesh_attachment_get_region = + _spine_mesh_attachment_get_regionPtr + .asFunction(); + + /// OMITTED setRegion() + spine_sequence spine_mesh_attachment_get_sequence( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_sequence( + attachment, + ); + } + + late final _spine_mesh_attachment_get_sequencePtr = _lookup< + ffi.NativeFunction>( + 'spine_mesh_attachment_get_sequence'); + late final _spine_mesh_attachment_get_sequence = + _spine_mesh_attachment_get_sequencePtr + .asFunction(); + + /// OMITTED setSequence() + spine_mesh_attachment spine_mesh_attachment_get_parent_mesh( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_parent_mesh( + attachment, + ); + } + + late final _spine_mesh_attachment_get_parent_meshPtr = _lookup< + ffi.NativeFunction< + spine_mesh_attachment Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_parent_mesh'); + late final _spine_mesh_attachment_get_parent_mesh = + _spine_mesh_attachment_get_parent_meshPtr + .asFunction(); + + void spine_mesh_attachment_set_parent_mesh( + spine_mesh_attachment attachment, + spine_mesh_attachment parentMesh, + ) { + return _spine_mesh_attachment_set_parent_mesh( + attachment, + parentMesh, + ); + } + + late final _spine_mesh_attachment_set_parent_meshPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_mesh_attachment, + spine_mesh_attachment)>>('spine_mesh_attachment_set_parent_mesh'); + late final _spine_mesh_attachment_set_parent_mesh = + _spine_mesh_attachment_set_parent_meshPtr.asFunction< + void Function(spine_mesh_attachment, spine_mesh_attachment)>(); + + int spine_mesh_attachment_get_num_edges( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_num_edges( + attachment, + ); + } + + late final _spine_mesh_attachment_get_num_edgesPtr = + _lookup>( + 'spine_mesh_attachment_get_num_edges'); + late final _spine_mesh_attachment_get_num_edges = + _spine_mesh_attachment_get_num_edgesPtr + .asFunction(); + + ffi.Pointer spine_mesh_attachment_get_edges( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_edges( + attachment, + ); + } + + late final _spine_mesh_attachment_get_edgesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_mesh_attachment)>>('spine_mesh_attachment_get_edges'); + late final _spine_mesh_attachment_get_edges = + _spine_mesh_attachment_get_edgesPtr.asFunction< + ffi.Pointer Function(spine_mesh_attachment)>(); + + double spine_mesh_attachment_get_width( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_width( + attachment, + ); + } + + late final _spine_mesh_attachment_get_widthPtr = + _lookup>( + 'spine_mesh_attachment_get_width'); + late final _spine_mesh_attachment_get_width = + _spine_mesh_attachment_get_widthPtr + .asFunction(); + + void spine_mesh_attachment_set_width( + spine_mesh_attachment attachment, + double width, + ) { + return _spine_mesh_attachment_set_width( + attachment, + width, + ); + } + + late final _spine_mesh_attachment_set_widthPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_mesh_attachment, + ffi.Float)>>('spine_mesh_attachment_set_width'); + late final _spine_mesh_attachment_set_width = + _spine_mesh_attachment_set_widthPtr + .asFunction(); + + double spine_mesh_attachment_get_height( + spine_mesh_attachment attachment, + ) { + return _spine_mesh_attachment_get_height( + attachment, + ); + } + + late final _spine_mesh_attachment_get_heightPtr = + _lookup>( + 'spine_mesh_attachment_get_height'); + late final _spine_mesh_attachment_get_height = + _spine_mesh_attachment_get_heightPtr + .asFunction(); + + void spine_mesh_attachment_set_height( + spine_mesh_attachment attachment, + double height, + ) { + return _spine_mesh_attachment_set_height( + attachment, + height, + ); + } + + late final _spine_mesh_attachment_set_heightPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_mesh_attachment, + ffi.Float)>>('spine_mesh_attachment_set_height'); + late final _spine_mesh_attachment_set_height = + _spine_mesh_attachment_set_heightPtr + .asFunction(); + + /// OMITTED newLinkedMesh() + spine_slot_data spine_clipping_attachment_get_end_slot( + spine_clipping_attachment attachment, + ) { + return _spine_clipping_attachment_get_end_slot( + attachment, + ); + } + + late final _spine_clipping_attachment_get_end_slotPtr = _lookup< + ffi.NativeFunction< + spine_slot_data Function(spine_clipping_attachment)>>( + 'spine_clipping_attachment_get_end_slot'); + late final _spine_clipping_attachment_get_end_slot = + _spine_clipping_attachment_get_end_slotPtr + .asFunction(); + + void spine_clipping_attachment_set_end_slot( + spine_clipping_attachment attachment, + spine_slot_data endSlot, + ) { + return _spine_clipping_attachment_set_end_slot( + attachment, + endSlot, + ); + } + + late final _spine_clipping_attachment_set_end_slotPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_clipping_attachment, + spine_slot_data)>>('spine_clipping_attachment_set_end_slot'); + late final _spine_clipping_attachment_set_end_slot = + _spine_clipping_attachment_set_end_slotPtr.asFunction< + void Function(spine_clipping_attachment, spine_slot_data)>(); + + spine_color spine_clipping_attachment_get_color( + spine_clipping_attachment attachment, + ) { + return _spine_clipping_attachment_get_color( + attachment, + ); + } + + late final _spine_clipping_attachment_get_colorPtr = _lookup< + ffi.NativeFunction>( + 'spine_clipping_attachment_get_color'); + late final _spine_clipping_attachment_get_color = + _spine_clipping_attachment_get_colorPtr + .asFunction(); + + void spine_clipping_attachment_set_color( + spine_clipping_attachment attachment, + double r, + double g, + double b, + double a, + ) { + return _spine_clipping_attachment_set_color( + attachment, + r, + g, + b, + a, + ); + } + + late final _spine_clipping_attachment_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_clipping_attachment, ffi.Float, ffi.Float, + ffi.Float, ffi.Float)>>('spine_clipping_attachment_set_color'); + late final _spine_clipping_attachment_set_color = + _spine_clipping_attachment_set_colorPtr.asFunction< + void Function( + spine_clipping_attachment, double, double, double, double)>(); + + spine_color spine_bounding_box_attachment_get_color( + spine_bounding_box_attachment attachment, + ) { + return _spine_bounding_box_attachment_get_color( + attachment, + ); + } + + late final _spine_bounding_box_attachment_get_colorPtr = _lookup< + ffi.NativeFunction< + spine_color Function(spine_bounding_box_attachment)>>( + 'spine_bounding_box_attachment_get_color'); + late final _spine_bounding_box_attachment_get_color = + _spine_bounding_box_attachment_get_colorPtr + .asFunction(); + + void spine_bounding_box_attachment_set_color( + spine_bounding_box_attachment attachment, + double r, + double g, + double b, + double a, + ) { + return _spine_bounding_box_attachment_set_color( + attachment, + r, + g, + b, + a, + ); + } + + late final _spine_bounding_box_attachment_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_bounding_box_attachment, + ffi.Float, + ffi.Float, + ffi.Float, + ffi.Float)>>('spine_bounding_box_attachment_set_color'); + late final _spine_bounding_box_attachment_set_color = + _spine_bounding_box_attachment_set_colorPtr.asFunction< + void Function( + spine_bounding_box_attachment, double, double, double, double)>(); + + int spine_path_attachment_get_num_lengths( + spine_path_attachment attachment, + ) { + return _spine_path_attachment_get_num_lengths( + attachment, + ); + } + + late final _spine_path_attachment_get_num_lengthsPtr = + _lookup>( + 'spine_path_attachment_get_num_lengths'); + late final _spine_path_attachment_get_num_lengths = + _spine_path_attachment_get_num_lengthsPtr + .asFunction(); + + ffi.Pointer spine_path_attachment_get_lengths( + spine_path_attachment attachment, + ) { + return _spine_path_attachment_get_lengths( + attachment, + ); + } + + late final _spine_path_attachment_get_lengthsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_path_attachment)>>('spine_path_attachment_get_lengths'); + late final _spine_path_attachment_get_lengths = + _spine_path_attachment_get_lengthsPtr + .asFunction Function(spine_path_attachment)>(); + + int spine_path_attachment_get_is_closed( + spine_path_attachment attachment, + ) { + return _spine_path_attachment_get_is_closed( + attachment, + ); + } + + late final _spine_path_attachment_get_is_closedPtr = + _lookup>( + 'spine_path_attachment_get_is_closed'); + late final _spine_path_attachment_get_is_closed = + _spine_path_attachment_get_is_closedPtr + .asFunction(); + + void spine_path_attachment_set_is_closed( + spine_path_attachment attachment, + int isClosed, + ) { + return _spine_path_attachment_set_is_closed( + attachment, + isClosed, + ); + } + + late final _spine_path_attachment_set_is_closedPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_attachment, + ffi.Int32)>>('spine_path_attachment_set_is_closed'); + late final _spine_path_attachment_set_is_closed = + _spine_path_attachment_set_is_closedPtr + .asFunction(); + + int spine_path_attachment_get_is_constant_speed( + spine_path_attachment attachment, + ) { + return _spine_path_attachment_get_is_constant_speed( + attachment, + ); + } + + late final _spine_path_attachment_get_is_constant_speedPtr = + _lookup>( + 'spine_path_attachment_get_is_constant_speed'); + late final _spine_path_attachment_get_is_constant_speed = + _spine_path_attachment_get_is_constant_speedPtr + .asFunction(); + + void spine_path_attachment_set_is_constant_speed( + spine_path_attachment attachment, + int isConstantSpeed, + ) { + return _spine_path_attachment_set_is_constant_speed( + attachment, + isConstantSpeed, + ); + } + + late final _spine_path_attachment_set_is_constant_speedPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_attachment, + ffi.Int32)>>('spine_path_attachment_set_is_constant_speed'); + late final _spine_path_attachment_set_is_constant_speed = + _spine_path_attachment_set_is_constant_speedPtr + .asFunction(); + + spine_color spine_path_attachment_get_color( + spine_path_attachment attachment, + ) { + return _spine_path_attachment_get_color( + attachment, + ); + } + + late final _spine_path_attachment_get_colorPtr = + _lookup>( + 'spine_path_attachment_get_color'); + late final _spine_path_attachment_get_color = + _spine_path_attachment_get_colorPtr + .asFunction(); + + void spine_path_attachment_set_color( + spine_path_attachment attachment, + double r, + double g, + double b, + double a, + ) { + return _spine_path_attachment_set_color( + attachment, + r, + g, + b, + a, + ); + } + + late final _spine_path_attachment_set_colorPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_attachment, ffi.Float, ffi.Float, + ffi.Float, ffi.Float)>>('spine_path_attachment_set_color'); + late final _spine_path_attachment_set_color = + _spine_path_attachment_set_colorPtr.asFunction< + void Function( + spine_path_attachment, double, double, double, double)>(); + + void spine_skin_set_attachment( + spine_skin skin, + int slotIndex, + ffi.Pointer name, + spine_attachment attachment, + ) { + return _spine_skin_set_attachment( + skin, + slotIndex, + name, + attachment, + ); + } + + late final _spine_skin_set_attachmentPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skin, ffi.Int32, ffi.Pointer, + spine_attachment)>>('spine_skin_set_attachment'); + late final _spine_skin_set_attachment = + _spine_skin_set_attachmentPtr.asFunction< + void Function( + spine_skin, int, ffi.Pointer, spine_attachment)>(); + + spine_attachment spine_skin_get_attachment( + spine_skin skin, + int slotIndex, + ffi.Pointer name, + ) { + return _spine_skin_get_attachment( + skin, + slotIndex, + name, + ); + } + + late final _spine_skin_get_attachmentPtr = _lookup< + ffi.NativeFunction< + spine_attachment Function(spine_skin, ffi.Int32, + ffi.Pointer)>>('spine_skin_get_attachment'); + late final _spine_skin_get_attachment = + _spine_skin_get_attachmentPtr.asFunction< + spine_attachment Function(spine_skin, int, ffi.Pointer)>(); + + void spine_skin_remove_attachment( + spine_skin skin, + int slotIndex, + ffi.Pointer name, + ) { + return _spine_skin_remove_attachment( + skin, + slotIndex, + name, + ); + } + + late final _spine_skin_remove_attachmentPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_skin, ffi.Int32, + ffi.Pointer)>>('spine_skin_remove_attachment'); + late final _spine_skin_remove_attachment = _spine_skin_remove_attachmentPtr + .asFunction)>(); + + /// OMITTED findNamesForSlot() + /// OMITTED findAttachmentsForSlot() + ffi.Pointer spine_skin_get_name( + spine_skin skin, + ) { + return _spine_skin_get_name( + skin, + ); + } + + late final _spine_skin_get_namePtr = + _lookup Function(spine_skin)>>( + 'spine_skin_get_name'); + late final _spine_skin_get_name = _spine_skin_get_namePtr + .asFunction Function(spine_skin)>(); + + void spine_skin_add_skin( + spine_skin skin, + spine_skin other, + ) { + return _spine_skin_add_skin( + skin, + other, + ); + } + + late final _spine_skin_add_skinPtr = + _lookup>( + 'spine_skin_add_skin'); + late final _spine_skin_add_skin = _spine_skin_add_skinPtr + .asFunction(); + + void spine_skin_copy_skin( + spine_skin skin, + spine_skin other, + ) { + return _spine_skin_copy_skin( + skin, + other, + ); + } + + late final _spine_skin_copy_skinPtr = + _lookup>( + 'spine_skin_copy_skin'); + late final _spine_skin_copy_skin = _spine_skin_copy_skinPtr + .asFunction(); + + spine_skin_entries spine_skin_get_entries( + spine_skin skin, + ) { + return _spine_skin_get_entries( + skin, + ); + } + + late final _spine_skin_get_entriesPtr = + _lookup>( + 'spine_skin_get_entries'); + late final _spine_skin_get_entries = _spine_skin_get_entriesPtr + .asFunction(); + + int spine_skin_entries_get_num_entries( + spine_skin_entries entries, + ) { + return _spine_skin_entries_get_num_entries( + entries, + ); + } + + late final _spine_skin_entries_get_num_entriesPtr = + _lookup>( + 'spine_skin_entries_get_num_entries'); + late final _spine_skin_entries_get_num_entries = + _spine_skin_entries_get_num_entriesPtr + .asFunction(); + + spine_skin_entry spine_skin_entries_get_entry( + spine_skin_entries entries, + int index, + ) { + return _spine_skin_entries_get_entry( + entries, + index, + ); + } + + late final _spine_skin_entries_get_entryPtr = _lookup< + ffi.NativeFunction< + spine_skin_entry Function( + spine_skin_entries, ffi.Int32)>>('spine_skin_entries_get_entry'); + late final _spine_skin_entries_get_entry = _spine_skin_entries_get_entryPtr + .asFunction(); + + void spine_skin_entries_dispose( + spine_skin_entries entries, + ) { + return _spine_skin_entries_dispose( + entries, + ); + } + + late final _spine_skin_entries_disposePtr = + _lookup>( + 'spine_skin_entries_dispose'); + late final _spine_skin_entries_dispose = _spine_skin_entries_disposePtr + .asFunction(); + + int spine_skin_entry_get_slot_index( + spine_skin_entry entry, + ) { + return _spine_skin_entry_get_slot_index( + entry, + ); + } + + late final _spine_skin_entry_get_slot_indexPtr = + _lookup>( + 'spine_skin_entry_get_slot_index'); + late final _spine_skin_entry_get_slot_index = + _spine_skin_entry_get_slot_indexPtr + .asFunction(); + + ffi.Pointer spine_skin_entry_get_name( + spine_skin_entry entry, + ) { + return _spine_skin_entry_get_name( + entry, + ); + } + + late final _spine_skin_entry_get_namePtr = + _lookup Function(spine_skin_entry)>>( + 'spine_skin_entry_get_name'); + late final _spine_skin_entry_get_name = _spine_skin_entry_get_namePtr + .asFunction Function(spine_skin_entry)>(); + + spine_attachment spine_skin_entry_get_attachment( + spine_skin_entry entry, + ) { + return _spine_skin_entry_get_attachment( + entry, + ); + } + + late final _spine_skin_entry_get_attachmentPtr = + _lookup>( + 'spine_skin_entry_get_attachment'); + late final _spine_skin_entry_get_attachment = + _spine_skin_entry_get_attachmentPtr + .asFunction(); + + int spine_skin_get_num_bones( + spine_skin skin, + ) { + return _spine_skin_get_num_bones( + skin, + ); + } + + late final _spine_skin_get_num_bonesPtr = + _lookup>( + 'spine_skin_get_num_bones'); + late final _spine_skin_get_num_bones = + _spine_skin_get_num_bonesPtr.asFunction(); + + ffi.Pointer spine_skin_get_bones( + spine_skin skin, + ) { + return _spine_skin_get_bones( + skin, + ); + } + + late final _spine_skin_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skin)>>('spine_skin_get_bones'); + late final _spine_skin_get_bones = _spine_skin_get_bonesPtr + .asFunction Function(spine_skin)>(); + + int spine_skin_get_num_constraints( + spine_skin skin, + ) { + return _spine_skin_get_num_constraints( + skin, + ); + } + + late final _spine_skin_get_num_constraintsPtr = + _lookup>( + 'spine_skin_get_num_constraints'); + late final _spine_skin_get_num_constraints = + _spine_skin_get_num_constraintsPtr.asFunction(); + + ffi.Pointer spine_skin_get_constraints( + spine_skin skin, + ) { + return _spine_skin_get_constraints( + skin, + ); + } + + late final _spine_skin_get_constraintsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_skin)>>('spine_skin_get_constraints'); + late final _spine_skin_get_constraints = _spine_skin_get_constraintsPtr + .asFunction Function(spine_skin)>(); + + spine_skin spine_skin_create( + ffi.Pointer name, + ) { + return _spine_skin_create( + name, + ); + } + + late final _spine_skin_createPtr = + _lookup)>>( + 'spine_skin_create'); + late final _spine_skin_create = _spine_skin_createPtr + .asFunction)>(); + + void spine_skin_dispose( + spine_skin skin, + ) { + return _spine_skin_dispose( + skin, + ); + } + + late final _spine_skin_disposePtr = + _lookup>( + 'spine_skin_dispose'); + late final _spine_skin_dispose = + _spine_skin_disposePtr.asFunction(); + + int spine_constraint_data_get_type( + spine_constraint_data data, + ) { + return _spine_constraint_data_get_type( + data, + ); + } + + late final _spine_constraint_data_get_typePtr = + _lookup>( + 'spine_constraint_data_get_type'); + late final _spine_constraint_data_get_type = + _spine_constraint_data_get_typePtr + .asFunction(); + + ffi.Pointer spine_constraint_data_get_name( + spine_constraint_data data, + ) { + return _spine_constraint_data_get_name( + data, + ); + } + + late final _spine_constraint_data_get_namePtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_constraint_data)>>('spine_constraint_data_get_name'); + late final _spine_constraint_data_get_name = + _spine_constraint_data_get_namePtr + .asFunction Function(spine_constraint_data)>(); + + int spine_constraint_data_get_order( + spine_constraint_data data, + ) { + return _spine_constraint_data_get_order( + data, + ); + } + + late final _spine_constraint_data_get_orderPtr = + _lookup>( + 'spine_constraint_data_get_order'); + late final _spine_constraint_data_get_order = + _spine_constraint_data_get_orderPtr + .asFunction(); + + void spine_constraint_data_set_order( + spine_constraint_data data, + int order, + ) { + return _spine_constraint_data_set_order( + data, + order, + ); + } + + late final _spine_constraint_data_set_orderPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_constraint_data, + ffi.Uint64)>>('spine_constraint_data_set_order'); + late final _spine_constraint_data_set_order = + _spine_constraint_data_set_orderPtr + .asFunction(); + + int spine_constraint_data_get_is_skin_required( + spine_constraint_data data, + ) { + return _spine_constraint_data_get_is_skin_required( + data, + ); + } + + late final _spine_constraint_data_get_is_skin_requiredPtr = + _lookup>( + 'spine_constraint_data_get_is_skin_required'); + late final _spine_constraint_data_get_is_skin_required = + _spine_constraint_data_get_is_skin_requiredPtr + .asFunction(); + + void spine_constraint_data_set_is_skin_required( + spine_constraint_data data, + int isSkinRequired, + ) { + return _spine_constraint_data_set_is_skin_required( + data, + isSkinRequired, + ); + } + + late final _spine_constraint_data_set_is_skin_requiredPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_constraint_data, + ffi.Int32)>>('spine_constraint_data_set_is_skin_required'); + late final _spine_constraint_data_set_is_skin_required = + _spine_constraint_data_set_is_skin_requiredPtr + .asFunction(); + + int spine_ik_constraint_data_get_num_bones( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_num_bones( + data, + ); + } + + late final _spine_ik_constraint_data_get_num_bonesPtr = + _lookup>( + 'spine_ik_constraint_data_get_num_bones'); + late final _spine_ik_constraint_data_get_num_bones = + _spine_ik_constraint_data_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_ik_constraint_data_get_bones( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_bones( + data, + ); + } + + late final _spine_ik_constraint_data_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_ik_constraint_data)>>('spine_ik_constraint_data_get_bones'); + late final _spine_ik_constraint_data_get_bones = + _spine_ik_constraint_data_get_bonesPtr.asFunction< + ffi.Pointer Function(spine_ik_constraint_data)>(); + + spine_bone_data spine_ik_constraint_data_get_target( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_target( + data, + ); + } + + late final _spine_ik_constraint_data_get_targetPtr = _lookup< + ffi.NativeFunction< + spine_bone_data Function(spine_ik_constraint_data)>>( + 'spine_ik_constraint_data_get_target'); + late final _spine_ik_constraint_data_get_target = + _spine_ik_constraint_data_get_targetPtr + .asFunction(); + + void spine_ik_constraint_data_set_target( + spine_ik_constraint_data data, + spine_bone_data target, + ) { + return _spine_ik_constraint_data_set_target( + data, + target, + ); + } + + late final _spine_ik_constraint_data_set_targetPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + spine_bone_data)>>('spine_ik_constraint_data_set_target'); + late final _spine_ik_constraint_data_set_target = + _spine_ik_constraint_data_set_targetPtr.asFunction< + void Function(spine_ik_constraint_data, spine_bone_data)>(); + + int spine_ik_constraint_data_get_bend_direction( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_bend_direction( + data, + ); + } + + late final _spine_ik_constraint_data_get_bend_directionPtr = + _lookup>( + 'spine_ik_constraint_data_get_bend_direction'); + late final _spine_ik_constraint_data_get_bend_direction = + _spine_ik_constraint_data_get_bend_directionPtr + .asFunction(); + + void spine_ik_constraint_data_set_bend_direction( + spine_ik_constraint_data data, + int bendDirection, + ) { + return _spine_ik_constraint_data_set_bend_direction( + data, + bendDirection, + ); + } + + late final _spine_ik_constraint_data_set_bend_directionPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + ffi.Int32)>>('spine_ik_constraint_data_set_bend_direction'); + late final _spine_ik_constraint_data_set_bend_direction = + _spine_ik_constraint_data_set_bend_directionPtr + .asFunction(); + + int spine_ik_constraint_data_get_compress( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_compress( + data, + ); + } + + late final _spine_ik_constraint_data_get_compressPtr = + _lookup>( + 'spine_ik_constraint_data_get_compress'); + late final _spine_ik_constraint_data_get_compress = + _spine_ik_constraint_data_get_compressPtr + .asFunction(); + + void spine_ik_constraint_data_set_compress( + spine_ik_constraint_data data, + int compress, + ) { + return _spine_ik_constraint_data_set_compress( + data, + compress, + ); + } + + late final _spine_ik_constraint_data_set_compressPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + ffi.Int32)>>('spine_ik_constraint_data_set_compress'); + late final _spine_ik_constraint_data_set_compress = + _spine_ik_constraint_data_set_compressPtr + .asFunction(); + + int spine_ik_constraint_data_get_stretch( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_stretch( + data, + ); + } + + late final _spine_ik_constraint_data_get_stretchPtr = + _lookup>( + 'spine_ik_constraint_data_get_stretch'); + late final _spine_ik_constraint_data_get_stretch = + _spine_ik_constraint_data_get_stretchPtr + .asFunction(); + + void spine_ik_constraint_data_set_stretch( + spine_ik_constraint_data data, + int stretch, + ) { + return _spine_ik_constraint_data_set_stretch( + data, + stretch, + ); + } + + late final _spine_ik_constraint_data_set_stretchPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + ffi.Int32)>>('spine_ik_constraint_data_set_stretch'); + late final _spine_ik_constraint_data_set_stretch = + _spine_ik_constraint_data_set_stretchPtr + .asFunction(); + + int spine_ik_constraint_data_get_uniform( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_uniform( + data, + ); + } + + late final _spine_ik_constraint_data_get_uniformPtr = + _lookup>( + 'spine_ik_constraint_data_get_uniform'); + late final _spine_ik_constraint_data_get_uniform = + _spine_ik_constraint_data_get_uniformPtr + .asFunction(); + + void spine_ik_constraint_data_set_uniform( + spine_ik_constraint_data data, + int uniform, + ) { + return _spine_ik_constraint_data_set_uniform( + data, + uniform, + ); + } + + late final _spine_ik_constraint_data_set_uniformPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + ffi.Int32)>>('spine_ik_constraint_data_set_uniform'); + late final _spine_ik_constraint_data_set_uniform = + _spine_ik_constraint_data_set_uniformPtr + .asFunction(); + + double spine_ik_constraint_data_get_mix( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_mix( + data, + ); + } + + late final _spine_ik_constraint_data_get_mixPtr = + _lookup>( + 'spine_ik_constraint_data_get_mix'); + late final _spine_ik_constraint_data_get_mix = + _spine_ik_constraint_data_get_mixPtr + .asFunction(); + + void spine_ik_constraint_data_set_mix( + spine_ik_constraint_data data, + double mix, + ) { + return _spine_ik_constraint_data_set_mix( + data, + mix, + ); + } + + late final _spine_ik_constraint_data_set_mixPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + ffi.Float)>>('spine_ik_constraint_data_set_mix'); + late final _spine_ik_constraint_data_set_mix = + _spine_ik_constraint_data_set_mixPtr + .asFunction(); + + double spine_ik_constraint_data_get_softness( + spine_ik_constraint_data data, + ) { + return _spine_ik_constraint_data_get_softness( + data, + ); + } + + late final _spine_ik_constraint_data_get_softnessPtr = + _lookup>( + 'spine_ik_constraint_data_get_softness'); + late final _spine_ik_constraint_data_get_softness = + _spine_ik_constraint_data_get_softnessPtr + .asFunction(); + + void spine_ik_constraint_data_set_softness( + spine_ik_constraint_data data, + double softness, + ) { + return _spine_ik_constraint_data_set_softness( + data, + softness, + ); + } + + late final _spine_ik_constraint_data_set_softnessPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint_data, + ffi.Float)>>('spine_ik_constraint_data_set_softness'); + late final _spine_ik_constraint_data_set_softness = + _spine_ik_constraint_data_set_softnessPtr + .asFunction(); + + void spine_ik_constraint_update( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_update( + constraint, + ); + } + + late final _spine_ik_constraint_updatePtr = + _lookup>( + 'spine_ik_constraint_update'); + late final _spine_ik_constraint_update = _spine_ik_constraint_updatePtr + .asFunction(); + + int spine_ik_constraint_get_order( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_order( + constraint, + ); + } + + late final _spine_ik_constraint_get_orderPtr = + _lookup>( + 'spine_ik_constraint_get_order'); + late final _spine_ik_constraint_get_order = _spine_ik_constraint_get_orderPtr + .asFunction(); + + spine_ik_constraint_data spine_ik_constraint_get_data( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_data( + constraint, + ); + } + + late final _spine_ik_constraint_get_dataPtr = _lookup< + ffi.NativeFunction< + spine_ik_constraint_data Function( + spine_ik_constraint)>>('spine_ik_constraint_get_data'); + late final _spine_ik_constraint_get_data = _spine_ik_constraint_get_dataPtr + .asFunction(); + + int spine_ik_constraint_get_num_bones( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_num_bones( + constraint, + ); + } + + late final _spine_ik_constraint_get_num_bonesPtr = + _lookup>( + 'spine_ik_constraint_get_num_bones'); + late final _spine_ik_constraint_get_num_bones = + _spine_ik_constraint_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_ik_constraint_get_bones( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_bones( + constraint, + ); + } + + late final _spine_ik_constraint_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_ik_constraint)>>('spine_ik_constraint_get_bones'); + late final _spine_ik_constraint_get_bones = _spine_ik_constraint_get_bonesPtr + .asFunction Function(spine_ik_constraint)>(); + + spine_bone spine_ik_constraint_get_target( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_target( + constraint, + ); + } + + late final _spine_ik_constraint_get_targetPtr = + _lookup>( + 'spine_ik_constraint_get_target'); + late final _spine_ik_constraint_get_target = + _spine_ik_constraint_get_targetPtr + .asFunction(); + + void spine_ik_constraint_set_target( + spine_ik_constraint constraint, + spine_bone target, + ) { + return _spine_ik_constraint_set_target( + constraint, + target, + ); + } + + late final _spine_ik_constraint_set_targetPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint, + spine_bone)>>('spine_ik_constraint_set_target'); + late final _spine_ik_constraint_set_target = + _spine_ik_constraint_set_targetPtr + .asFunction(); + + int spine_ik_constraint_get_bend_direction( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_bend_direction( + constraint, + ); + } + + late final _spine_ik_constraint_get_bend_directionPtr = + _lookup>( + 'spine_ik_constraint_get_bend_direction'); + late final _spine_ik_constraint_get_bend_direction = + _spine_ik_constraint_get_bend_directionPtr + .asFunction(); + + void spine_ik_constraint_set_bend_direction( + spine_ik_constraint constraint, + int bendDirection, + ) { + return _spine_ik_constraint_set_bend_direction( + constraint, + bendDirection, + ); + } + + late final _spine_ik_constraint_set_bend_directionPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint, + ffi.Int32)>>('spine_ik_constraint_set_bend_direction'); + late final _spine_ik_constraint_set_bend_direction = + _spine_ik_constraint_set_bend_directionPtr + .asFunction(); + + int spine_ik_constraint_get_compress( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_compress( + constraint, + ); + } + + late final _spine_ik_constraint_get_compressPtr = + _lookup>( + 'spine_ik_constraint_get_compress'); + late final _spine_ik_constraint_get_compress = + _spine_ik_constraint_get_compressPtr + .asFunction(); + + void spine_ik_constraint_set_compress( + spine_ik_constraint constraint, + int compress, + ) { + return _spine_ik_constraint_set_compress( + constraint, + compress, + ); + } + + late final _spine_ik_constraint_set_compressPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint, + ffi.Int32)>>('spine_ik_constraint_set_compress'); + late final _spine_ik_constraint_set_compress = + _spine_ik_constraint_set_compressPtr + .asFunction(); + + int spine_ik_constraint_get_stretch( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_stretch( + constraint, + ); + } + + late final _spine_ik_constraint_get_stretchPtr = + _lookup>( + 'spine_ik_constraint_get_stretch'); + late final _spine_ik_constraint_get_stretch = + _spine_ik_constraint_get_stretchPtr + .asFunction(); + + void spine_ik_constraint_set_stretch( + spine_ik_constraint constraint, + int stretch, + ) { + return _spine_ik_constraint_set_stretch( + constraint, + stretch, + ); + } + + late final _spine_ik_constraint_set_stretchPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint, + ffi.Int32)>>('spine_ik_constraint_set_stretch'); + late final _spine_ik_constraint_set_stretch = + _spine_ik_constraint_set_stretchPtr + .asFunction(); + + double spine_ik_constraint_get_mix( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_mix( + constraint, + ); + } + + late final _spine_ik_constraint_get_mixPtr = + _lookup>( + 'spine_ik_constraint_get_mix'); + late final _spine_ik_constraint_get_mix = _spine_ik_constraint_get_mixPtr + .asFunction(); + + void spine_ik_constraint_set_mix( + spine_ik_constraint constraint, + double mix, + ) { + return _spine_ik_constraint_set_mix( + constraint, + mix, + ); + } + + late final _spine_ik_constraint_set_mixPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_ik_constraint, ffi.Float)>>('spine_ik_constraint_set_mix'); + late final _spine_ik_constraint_set_mix = _spine_ik_constraint_set_mixPtr + .asFunction(); + + double spine_ik_constraint_get_softness( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_softness( + constraint, + ); + } + + late final _spine_ik_constraint_get_softnessPtr = + _lookup>( + 'spine_ik_constraint_get_softness'); + late final _spine_ik_constraint_get_softness = + _spine_ik_constraint_get_softnessPtr + .asFunction(); + + void spine_ik_constraint_set_softness( + spine_ik_constraint constraint, + double softness, + ) { + return _spine_ik_constraint_set_softness( + constraint, + softness, + ); + } + + late final _spine_ik_constraint_set_softnessPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint, + ffi.Float)>>('spine_ik_constraint_set_softness'); + late final _spine_ik_constraint_set_softness = + _spine_ik_constraint_set_softnessPtr + .asFunction(); + + int spine_ik_constraint_get_is_active( + spine_ik_constraint constraint, + ) { + return _spine_ik_constraint_get_is_active( + constraint, + ); + } + + late final _spine_ik_constraint_get_is_activePtr = + _lookup>( + 'spine_ik_constraint_get_is_active'); + late final _spine_ik_constraint_get_is_active = + _spine_ik_constraint_get_is_activePtr + .asFunction(); + + void spine_ik_constraint_set_is_active( + spine_ik_constraint constraint, + int isActive, + ) { + return _spine_ik_constraint_set_is_active( + constraint, + isActive, + ); + } + + late final _spine_ik_constraint_set_is_activePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_ik_constraint, + ffi.Int32)>>('spine_ik_constraint_set_is_active'); + late final _spine_ik_constraint_set_is_active = + _spine_ik_constraint_set_is_activePtr + .asFunction(); + + int spine_transform_constraint_data_get_num_bones( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_num_bones( + data, + ); + } + + late final _spine_transform_constraint_data_get_num_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Int32 Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_num_bones'); + late final _spine_transform_constraint_data_get_num_bones = + _spine_transform_constraint_data_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_transform_constraint_data_get_bones( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_bones( + data, + ); + } + + late final _spine_transform_constraint_data_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_bones'); + late final _spine_transform_constraint_data_get_bones = + _spine_transform_constraint_data_get_bonesPtr.asFunction< + ffi.Pointer Function( + spine_transform_constraint_data)>(); + + spine_bone_data spine_transform_constraint_data_get_target( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_target( + data, + ); + } + + late final _spine_transform_constraint_data_get_targetPtr = _lookup< + ffi.NativeFunction< + spine_bone_data Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_target'); + late final _spine_transform_constraint_data_get_target = + _spine_transform_constraint_data_get_targetPtr.asFunction< + spine_bone_data Function(spine_transform_constraint_data)>(); + + void spine_transform_constraint_data_set_target( + spine_transform_constraint_data data, + spine_bone_data target, + ) { + return _spine_transform_constraint_data_set_target( + data, + target, + ); + } + + late final _spine_transform_constraint_data_set_targetPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + spine_bone_data)>>('spine_transform_constraint_data_set_target'); + late final _spine_transform_constraint_data_set_target = + _spine_transform_constraint_data_set_targetPtr.asFunction< + void Function(spine_transform_constraint_data, spine_bone_data)>(); + + double spine_transform_constraint_data_get_mix_rotate( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_mix_rotate( + data, + ); + } + + late final _spine_transform_constraint_data_get_mix_rotatePtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_mix_rotate'); + late final _spine_transform_constraint_data_get_mix_rotate = + _spine_transform_constraint_data_get_mix_rotatePtr + .asFunction(); + + void spine_transform_constraint_data_set_mix_rotate( + spine_transform_constraint_data data, + double mixRotate, + ) { + return _spine_transform_constraint_data_set_mix_rotate( + data, + mixRotate, + ); + } + + late final _spine_transform_constraint_data_set_mix_rotatePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_mix_rotate'); + late final _spine_transform_constraint_data_set_mix_rotate = + _spine_transform_constraint_data_set_mix_rotatePtr + .asFunction(); + + double spine_transform_constraint_data_get_mix_x( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_mix_x( + data, + ); + } + + late final _spine_transform_constraint_data_get_mix_xPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_mix_x'); + late final _spine_transform_constraint_data_get_mix_x = + _spine_transform_constraint_data_get_mix_xPtr + .asFunction(); + + void spine_transform_constraint_data_set_mix_x( + spine_transform_constraint_data data, + double mixX, + ) { + return _spine_transform_constraint_data_set_mix_x( + data, + mixX, + ); + } + + late final _spine_transform_constraint_data_set_mix_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_mix_x'); + late final _spine_transform_constraint_data_set_mix_x = + _spine_transform_constraint_data_set_mix_xPtr + .asFunction(); + + double spine_transform_constraint_data_get_mix_y( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_mix_y( + data, + ); + } + + late final _spine_transform_constraint_data_get_mix_yPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_mix_y'); + late final _spine_transform_constraint_data_get_mix_y = + _spine_transform_constraint_data_get_mix_yPtr + .asFunction(); + + void spine_transform_constraint_data_set_mix_y( + spine_transform_constraint_data data, + double mixY, + ) { + return _spine_transform_constraint_data_set_mix_y( + data, + mixY, + ); + } + + late final _spine_transform_constraint_data_set_mix_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_mix_y'); + late final _spine_transform_constraint_data_set_mix_y = + _spine_transform_constraint_data_set_mix_yPtr + .asFunction(); + + double spine_transform_constraint_data_get_mix_scale_x( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_mix_scale_x( + data, + ); + } + + late final _spine_transform_constraint_data_get_mix_scale_xPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_mix_scale_x'); + late final _spine_transform_constraint_data_get_mix_scale_x = + _spine_transform_constraint_data_get_mix_scale_xPtr + .asFunction(); + + void spine_transform_constraint_data_set_mix_scale_x( + spine_transform_constraint_data data, + double mixScaleX, + ) { + return _spine_transform_constraint_data_set_mix_scale_x( + data, + mixScaleX, + ); + } + + late final _spine_transform_constraint_data_set_mix_scale_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_mix_scale_x'); + late final _spine_transform_constraint_data_set_mix_scale_x = + _spine_transform_constraint_data_set_mix_scale_xPtr + .asFunction(); + + double spine_transform_constraint_data_get_mix_scale_y( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_mix_scale_y( + data, + ); + } + + late final _spine_transform_constraint_data_get_mix_scale_yPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_mix_scale_y'); + late final _spine_transform_constraint_data_get_mix_scale_y = + _spine_transform_constraint_data_get_mix_scale_yPtr + .asFunction(); + + void spine_transform_constraint_data_set_mix_scale_y( + spine_transform_constraint_data data, + double mixScaleY, + ) { + return _spine_transform_constraint_data_set_mix_scale_y( + data, + mixScaleY, + ); + } + + late final _spine_transform_constraint_data_set_mix_scale_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_mix_scale_y'); + late final _spine_transform_constraint_data_set_mix_scale_y = + _spine_transform_constraint_data_set_mix_scale_yPtr + .asFunction(); + + double spine_transform_constraint_data_get_mix_shear_y( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_mix_shear_y( + data, + ); + } + + late final _spine_transform_constraint_data_get_mix_shear_yPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_mix_shear_y'); + late final _spine_transform_constraint_data_get_mix_shear_y = + _spine_transform_constraint_data_get_mix_shear_yPtr + .asFunction(); + + void spine_transform_constraint_data_set_mix_shear_y( + spine_transform_constraint_data data, + double mixShearY, + ) { + return _spine_transform_constraint_data_set_mix_shear_y( + data, + mixShearY, + ); + } + + late final _spine_transform_constraint_data_set_mix_shear_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_mix_shear_y'); + late final _spine_transform_constraint_data_set_mix_shear_y = + _spine_transform_constraint_data_set_mix_shear_yPtr + .asFunction(); + + double spine_transform_constraint_data_get_offset_rotation( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_offset_rotation( + data, + ); + } + + late final _spine_transform_constraint_data_get_offset_rotationPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_offset_rotation'); + late final _spine_transform_constraint_data_get_offset_rotation = + _spine_transform_constraint_data_get_offset_rotationPtr + .asFunction(); + + void spine_transform_constraint_data_set_offset_rotation( + spine_transform_constraint_data data, + double offsetRotation, + ) { + return _spine_transform_constraint_data_set_offset_rotation( + data, + offsetRotation, + ); + } + + late final _spine_transform_constraint_data_set_offset_rotationPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, ffi.Float)>>( + 'spine_transform_constraint_data_set_offset_rotation'); + late final _spine_transform_constraint_data_set_offset_rotation = + _spine_transform_constraint_data_set_offset_rotationPtr + .asFunction(); + + double spine_transform_constraint_data_get_offset_x( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_offset_x( + data, + ); + } + + late final _spine_transform_constraint_data_get_offset_xPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_offset_x'); + late final _spine_transform_constraint_data_get_offset_x = + _spine_transform_constraint_data_get_offset_xPtr + .asFunction(); + + void spine_transform_constraint_data_set_offset_x( + spine_transform_constraint_data data, + double offsetX, + ) { + return _spine_transform_constraint_data_set_offset_x( + data, + offsetX, + ); + } + + late final _spine_transform_constraint_data_set_offset_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_offset_x'); + late final _spine_transform_constraint_data_set_offset_x = + _spine_transform_constraint_data_set_offset_xPtr + .asFunction(); + + double spine_transform_constraint_data_get_offset_y( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_offset_y( + data, + ); + } + + late final _spine_transform_constraint_data_get_offset_yPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_offset_y'); + late final _spine_transform_constraint_data_get_offset_y = + _spine_transform_constraint_data_get_offset_yPtr + .asFunction(); + + void spine_transform_constraint_data_set_offset_y( + spine_transform_constraint_data data, + double offsetY, + ) { + return _spine_transform_constraint_data_set_offset_y( + data, + offsetY, + ); + } + + late final _spine_transform_constraint_data_set_offset_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Float)>>('spine_transform_constraint_data_set_offset_y'); + late final _spine_transform_constraint_data_set_offset_y = + _spine_transform_constraint_data_set_offset_yPtr + .asFunction(); + + double spine_transform_constraint_data_get_offset_scale_x( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_offset_scale_x( + data, + ); + } + + late final _spine_transform_constraint_data_get_offset_scale_xPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_offset_scale_x'); + late final _spine_transform_constraint_data_get_offset_scale_x = + _spine_transform_constraint_data_get_offset_scale_xPtr + .asFunction(); + + void spine_transform_constraint_data_set_offset_scale_x( + spine_transform_constraint_data data, + double offsetScaleX, + ) { + return _spine_transform_constraint_data_set_offset_scale_x( + data, + offsetScaleX, + ); + } + + late final _spine_transform_constraint_data_set_offset_scale_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, ffi.Float)>>( + 'spine_transform_constraint_data_set_offset_scale_x'); + late final _spine_transform_constraint_data_set_offset_scale_x = + _spine_transform_constraint_data_set_offset_scale_xPtr + .asFunction(); + + double spine_transform_constraint_data_get_offset_scale_y( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_offset_scale_y( + data, + ); + } + + late final _spine_transform_constraint_data_get_offset_scale_yPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_offset_scale_y'); + late final _spine_transform_constraint_data_get_offset_scale_y = + _spine_transform_constraint_data_get_offset_scale_yPtr + .asFunction(); + + void spine_transform_constraint_data_set_offset_scale_y( + spine_transform_constraint_data data, + double offsetScaleY, + ) { + return _spine_transform_constraint_data_set_offset_scale_y( + data, + offsetScaleY, + ); + } + + late final _spine_transform_constraint_data_set_offset_scale_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, ffi.Float)>>( + 'spine_transform_constraint_data_set_offset_scale_y'); + late final _spine_transform_constraint_data_set_offset_scale_y = + _spine_transform_constraint_data_set_offset_scale_yPtr + .asFunction(); + + double spine_transform_constraint_data_get_offset_shear_y( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_offset_shear_y( + data, + ); + } + + late final _spine_transform_constraint_data_get_offset_shear_yPtr = _lookup< + ffi.NativeFunction< + ffi.Float Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_offset_shear_y'); + late final _spine_transform_constraint_data_get_offset_shear_y = + _spine_transform_constraint_data_get_offset_shear_yPtr + .asFunction(); + + void spine_transform_constraint_data_set_offset_shear_y( + spine_transform_constraint_data data, + double offsetShearY, + ) { + return _spine_transform_constraint_data_set_offset_shear_y( + data, + offsetShearY, + ); + } + + late final _spine_transform_constraint_data_set_offset_shear_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, ffi.Float)>>( + 'spine_transform_constraint_data_set_offset_shear_y'); + late final _spine_transform_constraint_data_set_offset_shear_y = + _spine_transform_constraint_data_set_offset_shear_yPtr + .asFunction(); + + int spine_transform_constraint_data_get_is_relative( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_is_relative( + data, + ); + } + + late final _spine_transform_constraint_data_get_is_relativePtr = _lookup< + ffi.NativeFunction< + ffi.Int32 Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_is_relative'); + late final _spine_transform_constraint_data_get_is_relative = + _spine_transform_constraint_data_get_is_relativePtr + .asFunction(); + + void spine_transform_constraint_data_set_is_relative( + spine_transform_constraint_data data, + int isRelative, + ) { + return _spine_transform_constraint_data_set_is_relative( + data, + isRelative, + ); + } + + late final _spine_transform_constraint_data_set_is_relativePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Int32)>>('spine_transform_constraint_data_set_is_relative'); + late final _spine_transform_constraint_data_set_is_relative = + _spine_transform_constraint_data_set_is_relativePtr + .asFunction(); + + int spine_transform_constraint_data_get_is_local( + spine_transform_constraint_data data, + ) { + return _spine_transform_constraint_data_get_is_local( + data, + ); + } + + late final _spine_transform_constraint_data_get_is_localPtr = _lookup< + ffi.NativeFunction< + ffi.Int32 Function(spine_transform_constraint_data)>>( + 'spine_transform_constraint_data_get_is_local'); + late final _spine_transform_constraint_data_get_is_local = + _spine_transform_constraint_data_get_is_localPtr + .asFunction(); + + void spine_transform_constraint_data_set_is_local( + spine_transform_constraint_data data, + int isLocal, + ) { + return _spine_transform_constraint_data_set_is_local( + data, + isLocal, + ); + } + + late final _spine_transform_constraint_data_set_is_localPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint_data, + ffi.Int32)>>('spine_transform_constraint_data_set_is_local'); + late final _spine_transform_constraint_data_set_is_local = + _spine_transform_constraint_data_set_is_localPtr + .asFunction(); + + void spine_transform_constraint_update( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_update( + constraint, + ); + } + + late final _spine_transform_constraint_updatePtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_update'); + late final _spine_transform_constraint_update = + _spine_transform_constraint_updatePtr + .asFunction(); + + int spine_transform_constraint_get_order( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_order( + constraint, + ); + } + + late final _spine_transform_constraint_get_orderPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_order'); + late final _spine_transform_constraint_get_order = + _spine_transform_constraint_get_orderPtr + .asFunction(); + + spine_transform_constraint_data spine_transform_constraint_get_data( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_data( + constraint, + ); + } + + late final _spine_transform_constraint_get_dataPtr = _lookup< + ffi.NativeFunction< + spine_transform_constraint_data Function( + spine_transform_constraint)>>( + 'spine_transform_constraint_get_data'); + late final _spine_transform_constraint_get_data = + _spine_transform_constraint_get_dataPtr.asFunction< + spine_transform_constraint_data Function( + spine_transform_constraint)>(); + + int spine_transform_constraint_get_num_bones( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_num_bones( + constraint, + ); + } + + late final _spine_transform_constraint_get_num_bonesPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_num_bones'); + late final _spine_transform_constraint_get_num_bones = + _spine_transform_constraint_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_transform_constraint_get_bones( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_bones( + constraint, + ); + } + + late final _spine_transform_constraint_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function(spine_transform_constraint)>>( + 'spine_transform_constraint_get_bones'); + late final _spine_transform_constraint_get_bones = + _spine_transform_constraint_get_bonesPtr.asFunction< + ffi.Pointer Function(spine_transform_constraint)>(); + + spine_bone spine_transform_constraint_get_target( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_target( + constraint, + ); + } + + late final _spine_transform_constraint_get_targetPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_target'); + late final _spine_transform_constraint_get_target = + _spine_transform_constraint_get_targetPtr + .asFunction(); + + void spine_transform_constraint_set_target( + spine_transform_constraint constraint, + spine_bone target, + ) { + return _spine_transform_constraint_set_target( + constraint, + target, + ); + } + + late final _spine_transform_constraint_set_targetPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + spine_bone)>>('spine_transform_constraint_set_target'); + late final _spine_transform_constraint_set_target = + _spine_transform_constraint_set_targetPtr + .asFunction(); + + double spine_transform_constraint_get_mix_rotate( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_mix_rotate( + constraint, + ); + } + + late final _spine_transform_constraint_get_mix_rotatePtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_mix_rotate'); + late final _spine_transform_constraint_get_mix_rotate = + _spine_transform_constraint_get_mix_rotatePtr + .asFunction(); + + void spine_transform_constraint_set_mix_rotate( + spine_transform_constraint constraint, + double mixRotate, + ) { + return _spine_transform_constraint_set_mix_rotate( + constraint, + mixRotate, + ); + } + + late final _spine_transform_constraint_set_mix_rotatePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Float)>>('spine_transform_constraint_set_mix_rotate'); + late final _spine_transform_constraint_set_mix_rotate = + _spine_transform_constraint_set_mix_rotatePtr + .asFunction(); + + double spine_transform_constraint_get_mix_x( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_mix_x( + constraint, + ); + } + + late final _spine_transform_constraint_get_mix_xPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_mix_x'); + late final _spine_transform_constraint_get_mix_x = + _spine_transform_constraint_get_mix_xPtr + .asFunction(); + + void spine_transform_constraint_set_mix_x( + spine_transform_constraint constraint, + double mixX, + ) { + return _spine_transform_constraint_set_mix_x( + constraint, + mixX, + ); + } + + late final _spine_transform_constraint_set_mix_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Float)>>('spine_transform_constraint_set_mix_x'); + late final _spine_transform_constraint_set_mix_x = + _spine_transform_constraint_set_mix_xPtr + .asFunction(); + + double spine_transform_constraint_get_mix_y( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_mix_y( + constraint, + ); + } + + late final _spine_transform_constraint_get_mix_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_mix_y'); + late final _spine_transform_constraint_get_mix_y = + _spine_transform_constraint_get_mix_yPtr + .asFunction(); + + void spine_transform_constraint_set_mix_y( + spine_transform_constraint constraint, + double mixY, + ) { + return _spine_transform_constraint_set_mix_y( + constraint, + mixY, + ); + } + + late final _spine_transform_constraint_set_mix_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Float)>>('spine_transform_constraint_set_mix_y'); + late final _spine_transform_constraint_set_mix_y = + _spine_transform_constraint_set_mix_yPtr + .asFunction(); + + double spine_transform_constraint_get_mix_scale_x( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_mix_scale_x( + constraint, + ); + } + + late final _spine_transform_constraint_get_mix_scale_xPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_mix_scale_x'); + late final _spine_transform_constraint_get_mix_scale_x = + _spine_transform_constraint_get_mix_scale_xPtr + .asFunction(); + + void spine_transform_constraint_set_mix_scale_x( + spine_transform_constraint constraint, + double mixScaleX, + ) { + return _spine_transform_constraint_set_mix_scale_x( + constraint, + mixScaleX, + ); + } + + late final _spine_transform_constraint_set_mix_scale_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Float)>>('spine_transform_constraint_set_mix_scale_x'); + late final _spine_transform_constraint_set_mix_scale_x = + _spine_transform_constraint_set_mix_scale_xPtr + .asFunction(); + + double spine_transform_constraint_get_mix_scale_y( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_mix_scale_y( + constraint, + ); + } + + late final _spine_transform_constraint_get_mix_scale_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_mix_scale_y'); + late final _spine_transform_constraint_get_mix_scale_y = + _spine_transform_constraint_get_mix_scale_yPtr + .asFunction(); + + void spine_transform_constraint_set_mix_scale_y( + spine_transform_constraint constraint, + double mixScaleY, + ) { + return _spine_transform_constraint_set_mix_scale_y( + constraint, + mixScaleY, + ); + } + + late final _spine_transform_constraint_set_mix_scale_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Float)>>('spine_transform_constraint_set_mix_scale_y'); + late final _spine_transform_constraint_set_mix_scale_y = + _spine_transform_constraint_set_mix_scale_yPtr + .asFunction(); + + double spine_transform_constraint_get_mix_shear_y( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_mix_shear_y( + constraint, + ); + } + + late final _spine_transform_constraint_get_mix_shear_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_mix_shear_y'); + late final _spine_transform_constraint_get_mix_shear_y = + _spine_transform_constraint_get_mix_shear_yPtr + .asFunction(); + + void spine_transform_constraint_set_mix_shear_y( + spine_transform_constraint constraint, + double mixShearY, + ) { + return _spine_transform_constraint_set_mix_shear_y( + constraint, + mixShearY, + ); + } + + late final _spine_transform_constraint_set_mix_shear_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Float)>>('spine_transform_constraint_set_mix_shear_y'); + late final _spine_transform_constraint_set_mix_shear_y = + _spine_transform_constraint_set_mix_shear_yPtr + .asFunction(); + + double spine_transform_constraint_get_is_active( + spine_transform_constraint constraint, + ) { + return _spine_transform_constraint_get_is_active( + constraint, + ); + } + + late final _spine_transform_constraint_get_is_activePtr = _lookup< + ffi.NativeFunction>( + 'spine_transform_constraint_get_is_active'); + late final _spine_transform_constraint_get_is_active = + _spine_transform_constraint_get_is_activePtr + .asFunction(); + + void spine_transform_constraint_set_is_active( + spine_transform_constraint constraint, + int isActive, + ) { + return _spine_transform_constraint_set_is_active( + constraint, + isActive, + ); + } + + late final _spine_transform_constraint_set_is_activePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_transform_constraint, + ffi.Int32)>>('spine_transform_constraint_set_is_active'); + late final _spine_transform_constraint_set_is_active = + _spine_transform_constraint_set_is_activePtr + .asFunction(); + + int spine_path_constraint_data_get_num_bones( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_num_bones( + data, + ); + } + + late final _spine_path_constraint_data_get_num_bonesPtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_num_bones'); + late final _spine_path_constraint_data_get_num_bones = + _spine_path_constraint_data_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_path_constraint_data_get_bones( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_bones( + data, + ); + } + + late final _spine_path_constraint_data_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_path_constraint_data)>>( + 'spine_path_constraint_data_get_bones'); + late final _spine_path_constraint_data_get_bones = + _spine_path_constraint_data_get_bonesPtr.asFunction< + ffi.Pointer Function(spine_path_constraint_data)>(); + + spine_slot_data spine_path_constraint_data_get_target( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_target( + data, + ); + } + + late final _spine_path_constraint_data_get_targetPtr = _lookup< + ffi.NativeFunction< + spine_slot_data Function(spine_path_constraint_data)>>( + 'spine_path_constraint_data_get_target'); + late final _spine_path_constraint_data_get_target = + _spine_path_constraint_data_get_targetPtr + .asFunction(); + + void spine_path_constraint_data_set_target( + spine_path_constraint_data data, + spine_slot_data target, + ) { + return _spine_path_constraint_data_set_target( + data, + target, + ); + } + + late final _spine_path_constraint_data_set_targetPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + spine_slot_data)>>('spine_path_constraint_data_set_target'); + late final _spine_path_constraint_data_set_target = + _spine_path_constraint_data_set_targetPtr.asFunction< + void Function(spine_path_constraint_data, spine_slot_data)>(); + + int spine_path_constraint_data_get_position_mode( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_position_mode( + data, + ); + } + + late final _spine_path_constraint_data_get_position_modePtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_position_mode'); + late final _spine_path_constraint_data_get_position_mode = + _spine_path_constraint_data_get_position_modePtr + .asFunction(); + + void spine_path_constraint_data_set_position_mode( + spine_path_constraint_data data, + int positionMode, + ) { + return _spine_path_constraint_data_set_position_mode( + data, + positionMode, + ); + } + + late final _spine_path_constraint_data_set_position_modePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Int32)>>('spine_path_constraint_data_set_position_mode'); + late final _spine_path_constraint_data_set_position_mode = + _spine_path_constraint_data_set_position_modePtr + .asFunction(); + + int spine_path_constraint_data_get_spacing_mode( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_spacing_mode( + data, + ); + } + + late final _spine_path_constraint_data_get_spacing_modePtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_spacing_mode'); + late final _spine_path_constraint_data_get_spacing_mode = + _spine_path_constraint_data_get_spacing_modePtr + .asFunction(); + + void spine_path_constraint_data_set_spacing_mode( + spine_path_constraint_data data, + int spacingMode, + ) { + return _spine_path_constraint_data_set_spacing_mode( + data, + spacingMode, + ); + } + + late final _spine_path_constraint_data_set_spacing_modePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Int32)>>('spine_path_constraint_data_set_spacing_mode'); + late final _spine_path_constraint_data_set_spacing_mode = + _spine_path_constraint_data_set_spacing_modePtr + .asFunction(); + + int spine_path_constraint_data_get_rotate_mode( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_rotate_mode( + data, + ); + } + + late final _spine_path_constraint_data_get_rotate_modePtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_rotate_mode'); + late final _spine_path_constraint_data_get_rotate_mode = + _spine_path_constraint_data_get_rotate_modePtr + .asFunction(); + + void spine_path_constraint_data_set_rotate_mode( + spine_path_constraint_data data, + int rotateMode, + ) { + return _spine_path_constraint_data_set_rotate_mode( + data, + rotateMode, + ); + } + + late final _spine_path_constraint_data_set_rotate_modePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Int32)>>('spine_path_constraint_data_set_rotate_mode'); + late final _spine_path_constraint_data_set_rotate_mode = + _spine_path_constraint_data_set_rotate_modePtr + .asFunction(); + + double spine_path_constraint_data_get_offset_rotation( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_offset_rotation( + data, + ); + } + + late final _spine_path_constraint_data_get_offset_rotationPtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_offset_rotation'); + late final _spine_path_constraint_data_get_offset_rotation = + _spine_path_constraint_data_get_offset_rotationPtr + .asFunction(); + + void spine_path_constraint_data_set_offset_rotation( + spine_path_constraint_data data, + double offsetRotation, + ) { + return _spine_path_constraint_data_set_offset_rotation( + data, + offsetRotation, + ); + } + + late final _spine_path_constraint_data_set_offset_rotationPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Float)>>('spine_path_constraint_data_set_offset_rotation'); + late final _spine_path_constraint_data_set_offset_rotation = + _spine_path_constraint_data_set_offset_rotationPtr + .asFunction(); + + double spine_path_constraint_data_get_position( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_position( + data, + ); + } + + late final _spine_path_constraint_data_get_positionPtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_position'); + late final _spine_path_constraint_data_get_position = + _spine_path_constraint_data_get_positionPtr + .asFunction(); + + void spine_path_constraint_data_set_position( + spine_path_constraint_data data, + double position, + ) { + return _spine_path_constraint_data_set_position( + data, + position, + ); + } + + late final _spine_path_constraint_data_set_positionPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Float)>>('spine_path_constraint_data_set_position'); + late final _spine_path_constraint_data_set_position = + _spine_path_constraint_data_set_positionPtr + .asFunction(); + + double spine_path_constraint_data_get_spacing( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_spacing( + data, + ); + } + + late final _spine_path_constraint_data_get_spacingPtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_spacing'); + late final _spine_path_constraint_data_get_spacing = + _spine_path_constraint_data_get_spacingPtr + .asFunction(); + + void spine_path_constraint_data_set_spacing( + spine_path_constraint_data data, + double spacing, + ) { + return _spine_path_constraint_data_set_spacing( + data, + spacing, + ); + } + + late final _spine_path_constraint_data_set_spacingPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Float)>>('spine_path_constraint_data_set_spacing'); + late final _spine_path_constraint_data_set_spacing = + _spine_path_constraint_data_set_spacingPtr + .asFunction(); + + double spine_path_constraint_data_get_mix_rotate( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_mix_rotate( + data, + ); + } + + late final _spine_path_constraint_data_get_mix_rotatePtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_mix_rotate'); + late final _spine_path_constraint_data_get_mix_rotate = + _spine_path_constraint_data_get_mix_rotatePtr + .asFunction(); + + void spine_path_constraint_data_set_mix_rotate( + spine_path_constraint_data data, + double mixRotate, + ) { + return _spine_path_constraint_data_set_mix_rotate( + data, + mixRotate, + ); + } + + late final _spine_path_constraint_data_set_mix_rotatePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Float)>>('spine_path_constraint_data_set_mix_rotate'); + late final _spine_path_constraint_data_set_mix_rotate = + _spine_path_constraint_data_set_mix_rotatePtr + .asFunction(); + + double spine_path_constraint_data_get_mix_x( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_mix_x( + data, + ); + } + + late final _spine_path_constraint_data_get_mix_xPtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_mix_x'); + late final _spine_path_constraint_data_get_mix_x = + _spine_path_constraint_data_get_mix_xPtr + .asFunction(); + + void spine_path_constraint_data_set_mix_x( + spine_path_constraint_data data, + double mixX, + ) { + return _spine_path_constraint_data_set_mix_x( + data, + mixX, + ); + } + + late final _spine_path_constraint_data_set_mix_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Float)>>('spine_path_constraint_data_set_mix_x'); + late final _spine_path_constraint_data_set_mix_x = + _spine_path_constraint_data_set_mix_xPtr + .asFunction(); + + double spine_path_constraint_data_get_mix_y( + spine_path_constraint_data data, + ) { + return _spine_path_constraint_data_get_mix_y( + data, + ); + } + + late final _spine_path_constraint_data_get_mix_yPtr = _lookup< + ffi.NativeFunction>( + 'spine_path_constraint_data_get_mix_y'); + late final _spine_path_constraint_data_get_mix_y = + _spine_path_constraint_data_get_mix_yPtr + .asFunction(); + + void spine_path_constraint_data_set_mix_y( + spine_path_constraint_data data, + double mixY, + ) { + return _spine_path_constraint_data_set_mix_y( + data, + mixY, + ); + } + + late final _spine_path_constraint_data_set_mix_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint_data, + ffi.Float)>>('spine_path_constraint_data_set_mix_y'); + late final _spine_path_constraint_data_set_mix_y = + _spine_path_constraint_data_set_mix_yPtr + .asFunction(); + + void spine_path_constraint_update( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_update( + constraint, + ); + } + + late final _spine_path_constraint_updatePtr = + _lookup>( + 'spine_path_constraint_update'); + late final _spine_path_constraint_update = _spine_path_constraint_updatePtr + .asFunction(); + + int spine_path_constraint_get_order( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_order( + constraint, + ); + } + + late final _spine_path_constraint_get_orderPtr = + _lookup>( + 'spine_path_constraint_get_order'); + late final _spine_path_constraint_get_order = + _spine_path_constraint_get_orderPtr + .asFunction(); + + spine_path_constraint_data spine_path_constraint_get_data( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_data( + constraint, + ); + } + + late final _spine_path_constraint_get_dataPtr = _lookup< + ffi.NativeFunction< + spine_path_constraint_data Function( + spine_path_constraint)>>('spine_path_constraint_get_data'); + late final _spine_path_constraint_get_data = + _spine_path_constraint_get_dataPtr.asFunction< + spine_path_constraint_data Function(spine_path_constraint)>(); + + int spine_path_constraint_get_num_bones( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_num_bones( + constraint, + ); + } + + late final _spine_path_constraint_get_num_bonesPtr = + _lookup>( + 'spine_path_constraint_get_num_bones'); + late final _spine_path_constraint_get_num_bones = + _spine_path_constraint_get_num_bonesPtr + .asFunction(); + + ffi.Pointer spine_path_constraint_get_bones( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_bones( + constraint, + ); + } + + late final _spine_path_constraint_get_bonesPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_path_constraint)>>('spine_path_constraint_get_bones'); + late final _spine_path_constraint_get_bones = + _spine_path_constraint_get_bonesPtr.asFunction< + ffi.Pointer Function(spine_path_constraint)>(); + + spine_slot spine_path_constraint_get_target( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_target( + constraint, + ); + } + + late final _spine_path_constraint_get_targetPtr = + _lookup>( + 'spine_path_constraint_get_target'); + late final _spine_path_constraint_get_target = + _spine_path_constraint_get_targetPtr + .asFunction(); + + void spine_path_constraint_set_target( + spine_path_constraint constraint, + spine_slot target, + ) { + return _spine_path_constraint_set_target( + constraint, + target, + ); + } + + late final _spine_path_constraint_set_targetPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + spine_slot)>>('spine_path_constraint_set_target'); + late final _spine_path_constraint_set_target = + _spine_path_constraint_set_targetPtr + .asFunction(); + + double spine_path_constraint_get_position( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_position( + constraint, + ); + } + + late final _spine_path_constraint_get_positionPtr = + _lookup>( + 'spine_path_constraint_get_position'); + late final _spine_path_constraint_get_position = + _spine_path_constraint_get_positionPtr + .asFunction(); + + void spine_path_constraint_set_position( + spine_path_constraint constraint, + double position, + ) { + return _spine_path_constraint_set_position( + constraint, + position, + ); + } + + late final _spine_path_constraint_set_positionPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + ffi.Float)>>('spine_path_constraint_set_position'); + late final _spine_path_constraint_set_position = + _spine_path_constraint_set_positionPtr + .asFunction(); + + double spine_path_constraint_get_spacing( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_spacing( + constraint, + ); + } + + late final _spine_path_constraint_get_spacingPtr = + _lookup>( + 'spine_path_constraint_get_spacing'); + late final _spine_path_constraint_get_spacing = + _spine_path_constraint_get_spacingPtr + .asFunction(); + + void spine_path_constraint_set_spacing( + spine_path_constraint constraint, + double spacing, + ) { + return _spine_path_constraint_set_spacing( + constraint, + spacing, + ); + } + + late final _spine_path_constraint_set_spacingPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + ffi.Float)>>('spine_path_constraint_set_spacing'); + late final _spine_path_constraint_set_spacing = + _spine_path_constraint_set_spacingPtr + .asFunction(); + + double spine_path_constraint_get_mix_rotate( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_mix_rotate( + constraint, + ); + } + + late final _spine_path_constraint_get_mix_rotatePtr = + _lookup>( + 'spine_path_constraint_get_mix_rotate'); + late final _spine_path_constraint_get_mix_rotate = + _spine_path_constraint_get_mix_rotatePtr + .asFunction(); + + void spine_path_constraint_set_mix_rotate( + spine_path_constraint constraint, + double mixRotate, + ) { + return _spine_path_constraint_set_mix_rotate( + constraint, + mixRotate, + ); + } + + late final _spine_path_constraint_set_mix_rotatePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + ffi.Float)>>('spine_path_constraint_set_mix_rotate'); + late final _spine_path_constraint_set_mix_rotate = + _spine_path_constraint_set_mix_rotatePtr + .asFunction(); + + double spine_path_constraint_get_mix_x( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_mix_x( + constraint, + ); + } + + late final _spine_path_constraint_get_mix_xPtr = + _lookup>( + 'spine_path_constraint_get_mix_x'); + late final _spine_path_constraint_get_mix_x = + _spine_path_constraint_get_mix_xPtr + .asFunction(); + + void spine_path_constraint_set_mix_x( + spine_path_constraint constraint, + double mixX, + ) { + return _spine_path_constraint_set_mix_x( + constraint, + mixX, + ); + } + + late final _spine_path_constraint_set_mix_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + ffi.Float)>>('spine_path_constraint_set_mix_x'); + late final _spine_path_constraint_set_mix_x = + _spine_path_constraint_set_mix_xPtr + .asFunction(); + + double spine_path_constraint_get_mix_y( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_mix_y( + constraint, + ); + } + + late final _spine_path_constraint_get_mix_yPtr = + _lookup>( + 'spine_path_constraint_get_mix_y'); + late final _spine_path_constraint_get_mix_y = + _spine_path_constraint_get_mix_yPtr + .asFunction(); + + void spine_path_constraint_set_mix_y( + spine_path_constraint constraint, + double mixY, + ) { + return _spine_path_constraint_set_mix_y( + constraint, + mixY, + ); + } + + late final _spine_path_constraint_set_mix_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + ffi.Float)>>('spine_path_constraint_set_mix_y'); + late final _spine_path_constraint_set_mix_y = + _spine_path_constraint_set_mix_yPtr + .asFunction(); + + int spine_path_constraint_get_is_active( + spine_path_constraint constraint, + ) { + return _spine_path_constraint_get_is_active( + constraint, + ); + } + + late final _spine_path_constraint_get_is_activePtr = + _lookup>( + 'spine_path_constraint_get_is_active'); + late final _spine_path_constraint_get_is_active = + _spine_path_constraint_get_is_activePtr + .asFunction(); + + void spine_path_constraint_set_is_active( + spine_path_constraint constraint, + int isActive, + ) { + return _spine_path_constraint_set_is_active( + constraint, + isActive, + ); + } + + late final _spine_path_constraint_set_is_activePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_path_constraint, + ffi.Int32)>>('spine_path_constraint_set_is_active'); + late final _spine_path_constraint_set_is_active = + _spine_path_constraint_set_is_activePtr + .asFunction(); + + /// OMITTED copy() + void spine_sequence_apply( + spine_sequence sequence, + spine_slot slot, + spine_attachment attachment, + ) { + return _spine_sequence_apply( + sequence, + slot, + attachment, + ); + } + + late final _spine_sequence_applyPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_sequence, spine_slot, + spine_attachment)>>('spine_sequence_apply'); + late final _spine_sequence_apply = _spine_sequence_applyPtr.asFunction< + void Function(spine_sequence, spine_slot, spine_attachment)>(); + + ffi.Pointer spine_sequence_get_path( + spine_sequence sequence, + ffi.Pointer basePath, + int index, + ) { + return _spine_sequence_get_path( + sequence, + basePath, + index, + ); + } + + late final _spine_sequence_get_pathPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function(spine_sequence, ffi.Pointer, + ffi.Int32)>>('spine_sequence_get_path'); + late final _spine_sequence_get_path = _spine_sequence_get_pathPtr.asFunction< + ffi.Pointer Function(spine_sequence, ffi.Pointer, int)>(); + + int spine_sequence_get_id( + spine_sequence sequence, + ) { + return _spine_sequence_get_id( + sequence, + ); + } + + late final _spine_sequence_get_idPtr = + _lookup>( + 'spine_sequence_get_id'); + late final _spine_sequence_get_id = + _spine_sequence_get_idPtr.asFunction(); + + void spine_sequence_set_id( + spine_sequence sequence, + int id, + ) { + return _spine_sequence_set_id( + sequence, + id, + ); + } + + late final _spine_sequence_set_idPtr = + _lookup>( + 'spine_sequence_set_id'); + late final _spine_sequence_set_id = _spine_sequence_set_idPtr + .asFunction(); + + int spine_sequence_get_start( + spine_sequence sequence, + ) { + return _spine_sequence_get_start( + sequence, + ); + } + + late final _spine_sequence_get_startPtr = + _lookup>( + 'spine_sequence_get_start'); + late final _spine_sequence_get_start = + _spine_sequence_get_startPtr.asFunction(); + + void spine_sequence_set_start( + spine_sequence sequence, + int start, + ) { + return _spine_sequence_set_start( + sequence, + start, + ); + } + + late final _spine_sequence_set_startPtr = + _lookup>( + 'spine_sequence_set_start'); + late final _spine_sequence_set_start = _spine_sequence_set_startPtr + .asFunction(); + + int spine_sequence_get_digits( + spine_sequence sequence, + ) { + return _spine_sequence_get_digits( + sequence, + ); + } + + late final _spine_sequence_get_digitsPtr = + _lookup>( + 'spine_sequence_get_digits'); + late final _spine_sequence_get_digits = + _spine_sequence_get_digitsPtr.asFunction(); + + void spine_sequence_set_digits( + spine_sequence sequence, + int digits, + ) { + return _spine_sequence_set_digits( + sequence, + digits, + ); + } + + late final _spine_sequence_set_digitsPtr = + _lookup>( + 'spine_sequence_set_digits'); + late final _spine_sequence_set_digits = _spine_sequence_set_digitsPtr + .asFunction(); + + int spine_sequence_get_setup_index( + spine_sequence sequence, + ) { + return _spine_sequence_get_setup_index( + sequence, + ); + } + + late final _spine_sequence_get_setup_indexPtr = + _lookup>( + 'spine_sequence_get_setup_index'); + late final _spine_sequence_get_setup_index = + _spine_sequence_get_setup_indexPtr + .asFunction(); + + void spine_sequence_set_setup_index( + spine_sequence sequence, + int setupIndex, + ) { + return _spine_sequence_set_setup_index( + sequence, + setupIndex, + ); + } + + late final _spine_sequence_set_setup_indexPtr = + _lookup>( + 'spine_sequence_set_setup_index'); + late final _spine_sequence_set_setup_index = + _spine_sequence_set_setup_indexPtr + .asFunction(); + + int spine_sequence_get_num_regions( + spine_sequence sequence, + ) { + return _spine_sequence_get_num_regions( + sequence, + ); + } + + late final _spine_sequence_get_num_regionsPtr = + _lookup>( + 'spine_sequence_get_num_regions'); + late final _spine_sequence_get_num_regions = + _spine_sequence_get_num_regionsPtr + .asFunction(); + + ffi.Pointer spine_sequence_get_regions( + spine_sequence sequence, + ) { + return _spine_sequence_get_regions( + sequence, + ); + } + + late final _spine_sequence_get_regionsPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_sequence)>>('spine_sequence_get_regions'); + late final _spine_sequence_get_regions = _spine_sequence_get_regionsPtr + .asFunction Function(spine_sequence)>(); + + ffi.Pointer spine_texture_region_get_texture( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_texture( + textureRegion, + ); + } + + late final _spine_texture_region_get_texturePtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + spine_texture_region)>>('spine_texture_region_get_texture'); + late final _spine_texture_region_get_texture = + _spine_texture_region_get_texturePtr + .asFunction Function(spine_texture_region)>(); + + void spine_texture_region_set_texture( + spine_texture_region textureRegion, + ffi.Pointer texture, + ) { + return _spine_texture_region_set_texture( + textureRegion, + texture, + ); + } + + late final _spine_texture_region_set_texturePtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Pointer)>>('spine_texture_region_set_texture'); + late final _spine_texture_region_set_texture = + _spine_texture_region_set_texturePtr.asFunction< + void Function(spine_texture_region, ffi.Pointer)>(); + + double spine_texture_region_get_u( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_u( + textureRegion, + ); + } + + late final _spine_texture_region_get_uPtr = + _lookup>( + 'spine_texture_region_get_u'); + late final _spine_texture_region_get_u = _spine_texture_region_get_uPtr + .asFunction(); + + void spine_texture_region_set_u( + spine_texture_region textureRegion, + double u, + ) { + return _spine_texture_region_set_u( + textureRegion, + u, + ); + } + + late final _spine_texture_region_set_uPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_texture_region, ffi.Float)>>('spine_texture_region_set_u'); + late final _spine_texture_region_set_u = _spine_texture_region_set_uPtr + .asFunction(); + + double spine_texture_region_get_v( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_v( + textureRegion, + ); + } + + late final _spine_texture_region_get_vPtr = + _lookup>( + 'spine_texture_region_get_v'); + late final _spine_texture_region_get_v = _spine_texture_region_get_vPtr + .asFunction(); + + void spine_texture_region_set_v( + spine_texture_region textureRegion, + double v, + ) { + return _spine_texture_region_set_v( + textureRegion, + v, + ); + } + + late final _spine_texture_region_set_vPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_texture_region, ffi.Float)>>('spine_texture_region_set_v'); + late final _spine_texture_region_set_v = _spine_texture_region_set_vPtr + .asFunction(); + + double spine_texture_region_get_u2( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_u2( + textureRegion, + ); + } + + late final _spine_texture_region_get_u2Ptr = + _lookup>( + 'spine_texture_region_get_u2'); + late final _spine_texture_region_get_u2 = _spine_texture_region_get_u2Ptr + .asFunction(); + + void spine_texture_region_set_u2( + spine_texture_region textureRegion, + double u2, + ) { + return _spine_texture_region_set_u2( + textureRegion, + u2, + ); + } + + late final _spine_texture_region_set_u2Ptr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_texture_region, ffi.Float)>>('spine_texture_region_set_u2'); + late final _spine_texture_region_set_u2 = _spine_texture_region_set_u2Ptr + .asFunction(); + + double spine_texture_region_get_v2( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_v2( + textureRegion, + ); + } + + late final _spine_texture_region_get_v2Ptr = + _lookup>( + 'spine_texture_region_get_v2'); + late final _spine_texture_region_get_v2 = _spine_texture_region_get_v2Ptr + .asFunction(); + + void spine_texture_region_set_v2( + spine_texture_region textureRegion, + double v2, + ) { + return _spine_texture_region_set_v2( + textureRegion, + v2, + ); + } + + late final _spine_texture_region_set_v2Ptr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + spine_texture_region, ffi.Float)>>('spine_texture_region_set_v2'); + late final _spine_texture_region_set_v2 = _spine_texture_region_set_v2Ptr + .asFunction(); + + int spine_texture_region_get_degrees( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_degrees( + textureRegion, + ); + } + + late final _spine_texture_region_get_degreesPtr = + _lookup>( + 'spine_texture_region_get_degrees'); + late final _spine_texture_region_get_degrees = + _spine_texture_region_get_degreesPtr + .asFunction(); + + void spine_texture_region_set_degrees( + spine_texture_region textureRegion, + int degrees, + ) { + return _spine_texture_region_set_degrees( + textureRegion, + degrees, + ); + } + + late final _spine_texture_region_set_degreesPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Int32)>>('spine_texture_region_set_degrees'); + late final _spine_texture_region_set_degrees = + _spine_texture_region_set_degreesPtr + .asFunction(); + + double spine_texture_region_get_offset_x( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_offset_x( + textureRegion, + ); + } + + late final _spine_texture_region_get_offset_xPtr = + _lookup>( + 'spine_texture_region_get_offset_x'); + late final _spine_texture_region_get_offset_x = + _spine_texture_region_get_offset_xPtr + .asFunction(); + + void spine_texture_region_set_offset_x( + spine_texture_region textureRegion, + double offsetX, + ) { + return _spine_texture_region_set_offset_x( + textureRegion, + offsetX, + ); + } + + late final _spine_texture_region_set_offset_xPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Float)>>('spine_texture_region_set_offset_x'); + late final _spine_texture_region_set_offset_x = + _spine_texture_region_set_offset_xPtr + .asFunction(); + + double spine_texture_region_get_offset_y( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_offset_y( + textureRegion, + ); + } + + late final _spine_texture_region_get_offset_yPtr = + _lookup>( + 'spine_texture_region_get_offset_y'); + late final _spine_texture_region_get_offset_y = + _spine_texture_region_get_offset_yPtr + .asFunction(); + + void spine_texture_region_set_offset_y( + spine_texture_region textureRegion, + double offsetY, + ) { + return _spine_texture_region_set_offset_y( + textureRegion, + offsetY, + ); + } + + late final _spine_texture_region_set_offset_yPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Float)>>('spine_texture_region_set_offset_y'); + late final _spine_texture_region_set_offset_y = + _spine_texture_region_set_offset_yPtr + .asFunction(); + + int spine_texture_region_get_width( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_width( + textureRegion, + ); + } + + late final _spine_texture_region_get_widthPtr = + _lookup>( + 'spine_texture_region_get_width'); + late final _spine_texture_region_get_width = + _spine_texture_region_get_widthPtr + .asFunction(); + + void spine_texture_region_set_width( + spine_texture_region textureRegion, + int width, + ) { + return _spine_texture_region_set_width( + textureRegion, + width, + ); + } + + late final _spine_texture_region_set_widthPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Int32)>>('spine_texture_region_set_width'); + late final _spine_texture_region_set_width = + _spine_texture_region_set_widthPtr + .asFunction(); + + int spine_texture_region_get_height( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_height( + textureRegion, + ); + } + + late final _spine_texture_region_get_heightPtr = + _lookup>( + 'spine_texture_region_get_height'); + late final _spine_texture_region_get_height = + _spine_texture_region_get_heightPtr + .asFunction(); + + void spine_texture_region_set_height( + spine_texture_region textureRegion, + int height, + ) { + return _spine_texture_region_set_height( + textureRegion, + height, + ); + } + + late final _spine_texture_region_set_heightPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Int32)>>('spine_texture_region_set_height'); + late final _spine_texture_region_set_height = + _spine_texture_region_set_heightPtr + .asFunction(); + + int spine_texture_region_get_original_width( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_original_width( + textureRegion, + ); + } + + late final _spine_texture_region_get_original_widthPtr = + _lookup>( + 'spine_texture_region_get_original_width'); + late final _spine_texture_region_get_original_width = + _spine_texture_region_get_original_widthPtr + .asFunction(); + + void spine_texture_region_set_original_width( + spine_texture_region textureRegion, + int originalWidth, + ) { + return _spine_texture_region_set_original_width( + textureRegion, + originalWidth, + ); + } + + late final _spine_texture_region_set_original_widthPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Int32)>>('spine_texture_region_set_original_width'); + late final _spine_texture_region_set_original_width = + _spine_texture_region_set_original_widthPtr + .asFunction(); + + int spine_texture_region_get_original_height( + spine_texture_region textureRegion, + ) { + return _spine_texture_region_get_original_height( + textureRegion, + ); + } + + late final _spine_texture_region_get_original_heightPtr = + _lookup>( + 'spine_texture_region_get_original_height'); + late final _spine_texture_region_get_original_height = + _spine_texture_region_get_original_heightPtr + .asFunction(); + + void spine_texture_region_set_original_height( + spine_texture_region textureRegion, + int originalHeight, + ) { + return _spine_texture_region_set_original_height( + textureRegion, + originalHeight, + ); + } + + late final _spine_texture_region_set_original_heightPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function(spine_texture_region, + ffi.Int32)>>('spine_texture_region_set_original_height'); + late final _spine_texture_region_set_original_height = + _spine_texture_region_set_original_heightPtr + .asFunction(); +} + +class spine_skeleton_wrapper extends ffi.Opaque {} + +class spine_skeleton_data_wrapper extends ffi.Opaque {} + +class spine_bone_wrapper extends ffi.Opaque {} + +class spine_bone_data_wrapper extends ffi.Opaque {} + +class spine_slot_wrapper extends ffi.Opaque {} + +class spine_slot_data_wrapper extends ffi.Opaque {} + +class spine_skin_wrapper extends ffi.Opaque {} + +class spine_attachment_wrapper extends ffi.Opaque {} + +class spine_region_attachment_wrapper extends ffi.Opaque {} + +class spine_vertex_attachment_wrapper extends ffi.Opaque {} + +class spine_mesh_attachment_wrapper extends ffi.Opaque {} + +class spine_clipping_attachment_wrapper extends ffi.Opaque {} + +class spine_bounding_box_attachment_wrapper extends ffi.Opaque {} + +class spine_path_attachment_wrapper extends ffi.Opaque {} + +class spine_point_attachment_wrapper extends ffi.Opaque {} + +class spine_texture_region_wrapper extends ffi.Opaque {} + +class spine_sequence_wrapper extends ffi.Opaque {} + +class spine_constraint_wrapper extends ffi.Opaque {} + +class spine_constraint_data_wrapper extends ffi.Opaque {} + +class spine_ik_constraint_wrapper extends ffi.Opaque {} + +class spine_ik_constraint_data_wrapper extends ffi.Opaque {} + +class spine_transform_constraint_wrapper extends ffi.Opaque {} + +class spine_transform_constraint_data_wrapper extends ffi.Opaque {} + +class spine_path_constraint_wrapper extends ffi.Opaque {} + +class spine_path_constraint_data_wrapper extends ffi.Opaque {} + +class spine_animation_state_wrapper extends ffi.Opaque {} + +class spine_animation_state_data_wrapper extends ffi.Opaque {} + +class spine_animation_state_events_wrapper extends ffi.Opaque {} + +class spine_event_wrapper extends ffi.Opaque {} + +class spine_event_data_wrapper extends ffi.Opaque {} + +class spine_track_entry_wrapper extends ffi.Opaque {} + +class spine_animation_wrapper extends ffi.Opaque {} + +class spine_atlas_wrapper extends ffi.Opaque {} + +class spine_skeleton_data_result_wrapper extends ffi.Opaque {} + +class spine_render_command_wrapper extends ffi.Opaque {} + +class spine_bounds_wrapper extends ffi.Opaque {} + +class spine_color_wrapper extends ffi.Opaque {} + +class spine_vector_wrapper extends ffi.Opaque {} + +class spine_skeleton_drawable_wrapper extends ffi.Opaque {} + +class spine_skin_entry_wrapper extends ffi.Opaque {} + +class spine_skin_entries_wrapper extends ffi.Opaque {} + +abstract class spine_blend_mode { + static const int SPINE_BLEND_MODE_NORMAL = 0; + static const int SPINE_BLEND_MODE_ADDITIVE = 1; + static const int SPINE_BLEND_MODE_MULTIPLY = 2; + static const int SPINE_BLEND_MODE_SCREEN = 3; +} + +abstract class spine_mix_blend { + static const int SPINE_MIX_BLEND_SETUP = 0; + static const int SPINE_MIX_BLEND_FIRST = 1; + static const int SPINE_MIX_BLEND_REPLACE = 2; + static const int SPINE_MIX_BLEND_ADD = 3; +} + +abstract class spine_event_type { + static const int SPINE_EVENT_TYPE_START = 0; + static const int SPINE_EVENT_TYPE_INTERRUPT = 1; + static const int SPINE_EVENT_TYPE_END = 2; + static const int SPINE_EVENT_TYPE_COMPLETE = 3; + static const int SPINE_EVENT_TYPE_DISPOSE = 4; + static const int SPINE_EVENT_TYPE_EVENT = 5; +} + +abstract class spine_attachment_type { + static const int SPINE_ATTACHMENT_REGION = 0; + static const int SPINE_ATTACHMENT_MESH = 1; + static const int SPINE_ATTACHMENT_CLIPPING = 2; + static const int SPINE_ATTACHMENT_BOUNDING_BOX = 3; + static const int SPINE_ATTACHMENT_PATH = 4; + static const int SPINE_ATTACHMENT_POINT = 5; +} + +abstract class spine_constraint_type { + static const int SPINE_CONSTRAINT_IK = 0; + static const int SPINE_CONSTRAINT_TRANSFORM = 1; + static const int SPINE_CONSTRAINT_PATH = 2; +} + +abstract class spine_transform_mode { + static const int SPINE_TRANSFORM_MODE_NORMAL = 0; + static const int SPINE_TRANSFORM_ONLY_TRANSLATION = 1; + static const int SPINE_TRANSFORM_NO_ROTATION_OR_REFLECTION = 2; + static const int SPINE_TRANSFORM_NO_SCALE = 3; + static const int SPINE_TRANSFORM_NO_SCALE_OR_REFLECTION = 4; +} + +abstract class spine_position_mode { + static const int SPINE_POSITION_MODE_FIXED = 0; + static const int SPINE_POSITION_MODE_PERCENT = 1; +} + +abstract class spine_spacing_mode { + static const int SPINE_SPACING_MODE_LENGTH = 0; + static const int SPINE_SPACING_MODE_FIXED = 1; + static const int SPINE_SPACING_MODE_PERCENT = 2; + static const int SPINE_SPACING_MODE_PROPORTIONAL = 3; +} + +abstract class spine_rotate_mode { + static const int SPINE_ROTATE_MODE_TANGENT = 0; + static const int SPINE_ROTATE_MODE_CHAIN = 1; + static const int SPINE_ROTATE_MODE_CHAIN_SCALE = 2; +} + +typedef spine_color = ffi.Pointer; +typedef spine_bounds = ffi.Pointer; +typedef spine_vector = ffi.Pointer; +typedef spine_atlas = ffi.Pointer; +typedef utf8 = ffi.Char; +typedef spine_skeleton_data_result + = ffi.Pointer; +typedef spine_skeleton_data = ffi.Pointer; +typedef spine_bone_data = ffi.Pointer; +typedef spine_slot_data = ffi.Pointer; +typedef spine_skin = ffi.Pointer; +typedef spine_event_data = ffi.Pointer; +typedef spine_animation = ffi.Pointer; +typedef spine_ik_constraint_data + = ffi.Pointer; +typedef spine_transform_constraint_data + = ffi.Pointer; +typedef spine_path_constraint_data + = ffi.Pointer; +typedef spine_skeleton_drawable = ffi.Pointer; +typedef spine_render_command = ffi.Pointer; +typedef spine_skeleton = ffi.Pointer; +typedef spine_animation_state = ffi.Pointer; +typedef spine_animation_state_data + = ffi.Pointer; +typedef spine_animation_state_events + = ffi.Pointer; +typedef spine_track_entry = ffi.Pointer; +typedef spine_event = ffi.Pointer; +typedef spine_bone = ffi.Pointer; +typedef spine_slot = ffi.Pointer; +typedef spine_attachment = ffi.Pointer; +typedef spine_ik_constraint = ffi.Pointer; +typedef spine_transform_constraint + = ffi.Pointer; +typedef spine_path_constraint = ffi.Pointer; +typedef spine_point_attachment = ffi.Pointer; +typedef spine_region_attachment = ffi.Pointer; +typedef spine_texture_region = ffi.Pointer; +typedef spine_sequence = ffi.Pointer; +typedef spine_vertex_attachment = ffi.Pointer; +typedef spine_mesh_attachment = ffi.Pointer; +typedef spine_clipping_attachment + = ffi.Pointer; +typedef spine_bounding_box_attachment + = ffi.Pointer; +typedef spine_path_attachment = ffi.Pointer; +typedef spine_skin_entries = ffi.Pointer; +typedef spine_skin_entry = ffi.Pointer; +typedef spine_constraint_data = ffi.Pointer; diff --git a/spine-flutter/lib/spine_widget.dart b/spine-flutter/lib/spine_widget.dart new file mode 100644 index 000000000..c34d46a6d --- /dev/null +++ b/spine-flutter/lib/spine_widget.dart @@ -0,0 +1,646 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated September 24, 2021. Replaces all prior versions. + * + * Copyright (c) 2013-2021, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +import 'dart:math'; + +import 'package:flutter/rendering.dart' as rendering; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +import 'spine_flutter.dart'; + +/// Controls how the skeleton of a [SpineWidget] is animated and rendered. +/// +/// Upon initialization of a [SpineWidget] the provided [onInitialized] callback method is called once. This method can be used +/// to setup the initial animation(s) of the skeleton, among other things. +/// +/// After initialization is complete, the [SpineWidget] is rendered at the screen refresh rate. In each frame, +/// the [AnimationState] is updated and applied to the [Skeleton]. +/// +/// Next the optionally provided method [onBeforeUpdateWorldTransforms] is called, which can modify the +/// skeleton before its current pose is calculated using [Skeleton.updateWorldTransforms]. After +/// [Skeleton.updateWorldTransforms] has completed, the optional [onAfterUpdateWorldTransforms] method is +/// called, which can modify the current pose before rendering the skeleton. +/// +/// Before the skeleton's current pose is rendered by the [SpineWidget] the optional [onBeforePaint] is called, +/// which allows rendering backgrounds or other objects that should go behind the skeleton on the [Canvas]. The +/// [SpineWidget] then renderes the skeleton's current pose, and finally calls the optional [onAfterPaint], which +/// can render additional objects on top of the skeleton. +/// +/// The underlying [Atlas], [SkeletonData], [Skeleton], [AnimationStateData], [AnimationState], and [SkeletonDrawable] +/// can be accessed through their respective getters to inspect and/or modify the skeleton and its associated data. Accessing +/// this data is only allowed if the [SpineWidget] and its data have been initialized and have not been disposed yet. +/// +/// By default, the widget updates and renders the skeleton every frame. The [pause] method can be used to pause updating +/// and rendering the skeleton. The [resume] method resumes updating and rendering the skeleton. The [isPlaying] getter +/// reports the current state. +class SpineWidgetController { + SkeletonDrawable? _drawable; + double _offsetX = 0, _offsetY = 0, _scaleX = 1, _scaleY = 1; + bool _isPlaying = true; + _SpineRenderObject? _renderObject = null; + final void Function(SpineWidgetController controller)? onInitialized; + final void Function(SpineWidgetController controller)? onBeforeUpdateWorldTransforms; + final void Function(SpineWidgetController controller)? onAfterUpdateWorldTransforms; + final void Function(SpineWidgetController controller, Canvas canvas)? onBeforePaint; + final void Function(SpineWidgetController controller, Canvas canvas, List commands)? onAfterPaint; + + /// Constructs a new [SpineWidget] controller. See the class documentation of [SpineWidgetController] for information on + /// the optional arguments. + SpineWidgetController( + {this.onInitialized, this.onBeforeUpdateWorldTransforms, this.onAfterUpdateWorldTransforms, this.onBeforePaint, this.onAfterPaint}); + + void _initialize(SkeletonDrawable drawable) { + if (_drawable != null) throw Exception("SpineWidgetController already initialized. A controller can only be used with one widget."); + _drawable = drawable; + onInitialized?.call(this); + } + + /// The [Atlas] from which images to render the skeleton are sourced. + Atlas get atlas { + if (_drawable == null) throw Exception("Controller is not initialized yet."); + return _drawable!.atlas; + } + + /// The setup-pose data used by the skeleton. + SkeletonData get skeletonData { + if (_drawable == null) throw Exception("Controller is not initialized yet."); + return _drawable!.skeletonData; + } + + /// The mixing information used by the [AnimationState] + AnimationStateData get animationStateData { + if (_drawable == null) throw Exception("Controller is not initialized yet."); + return _drawable!.animationStateData; + } + + /// The [AnimationState] used to manage animations that are being applied to the + /// skeleton. + AnimationState get animationState { + if (_drawable == null) throw Exception("Controller is not initialized yet."); + return _drawable!.animationState; + } + + /// The [Skeleton] + Skeleton get skeleton { + if (_drawable == null) throw Exception("Controller is not initialized yet."); + return _drawable!.skeleton; + } + + /// The [SkeletonDrawable] + SkeletonDrawable get drawable { + if (_drawable == null) throw Exception("Controller is not initialized yet."); + return _drawable!; + } + + void _setCoordinateTransform(double offsetX, double offsetY, double scaleX, double scaleY) { + _offsetX = offsetX; + _offsetY = offsetY; + _scaleX = scaleX; + _scaleY = scaleY; + } + + void _setRenderObject(_SpineRenderObject? renderObject) { + _renderObject = renderObject; + } + + /// Transforms the coordinates given in the [SpineWidget] coordinate system in [position] to + /// the skeleton coordinate system. See the `ik_following.dart` example how to use this + /// to move a bone based on user touch input. + Offset toSkeletonCoordinates(Offset position) { + var x = position.dx; + var y = position.dy; + return Offset(x / _scaleX - _offsetX, y / _scaleY - _offsetY); + } + + /// Pauses updating and rendering the skeleton. + void pause() { + _isPlaying = false; + } + + /// Resumes updating and rendering the skeleton. + void resume() { + _isPlaying = true; + _renderObject?._stopwatch.reset(); + _renderObject?._stopwatch.start(); + _renderObject?._scheduleFrame(); + } + + bool get isPlaying { + return _isPlaying; + } +} + +enum _AssetType { asset, file, http, drawable } + +/// Base class for bounds providers. A bounds provider calculates the axis aligned bounding box +/// used to scale and fit a skeleton inside the bounds of a [SpineWidget]. +abstract class BoundsProvider { + const BoundsProvider(); + + Bounds computeBounds(SkeletonDrawable drawable); +} + +/// A [BoundsProvider] that calculates the bounding box of the skeleton based on the visible +/// attachments in the setup pose. +class SetupPoseBounds extends BoundsProvider { + const SetupPoseBounds(); + + @override + Bounds computeBounds(SkeletonDrawable drawable) { + return drawable.skeleton.getBounds(); + } +} + +/// A [BoundsProvider] that returns fixed bounds. +class RawBounds extends BoundsProvider { + final double x, y, width, height; + + RawBounds(this.x, this.y, this.width, this.height); + + @override + Bounds computeBounds(SkeletonDrawable drawable) { + return Bounds(x, y, width, height); + } +} + +/// A [BoundsProvider] that calculates the bounding box needed for a combination of skins +/// and an animation. +class SkinAndAnimationBounds extends BoundsProvider { + final List skins; + final String? animation; + final double stepTime; + + /// Constructs a new provider that will use the given [skins] and [animation] to calculate + /// the bounding box of the skeleton. If no skins are given, the default skin is used. + /// The [stepTime], given in seconds, defines at what interval the bounds should be sampled + /// across the entire animation. + SkinAndAnimationBounds({List? skins, this.animation, this.stepTime = 0.1}) + : skins = skins == null || skins.isEmpty ? ["default"] : skins; + + @override + Bounds computeBounds(SkeletonDrawable drawable) { + final data = drawable.skeletonData; + final oldSkin = drawable.skeleton.getSkin(); + final customSkin = Skin("custom-skin"); + for (final skinName in skins) { + final skin = data.findSkin(skinName); + if (skin == null) continue; + customSkin.addSkin(skin); + } + drawable.skeleton.setSkin(customSkin); + drawable.skeleton.setToSetupPose(); + + final animation = this.animation != null ? data.findAnimation(this.animation!) : null; + double minX = double.infinity; + double minY = double.infinity; + double maxX = double.negativeInfinity; + double maxY = double.negativeInfinity; + if (animation == null) { + final bounds = drawable.skeleton.getBounds(); + minX = bounds.x; + minY = bounds.y; + maxX = minX + bounds.width; + maxY = minY + bounds.height; + } else { + drawable.animationState.setAnimation(0, animation, false); + final steps = max(animation.getDuration() / stepTime, 1.0).toInt(); + for (int i = 0; i < steps; i++) { + drawable.update(i > 0 ? stepTime : 0); + final bounds = drawable.skeleton.getBounds(); + minX = min(minX, bounds.x); + minY = min(minY, bounds.y); + maxX = max(maxX, minX + bounds.width); + maxY = max(maxY, minY + bounds.height); + } + } + drawable.skeleton.setSkinByName("default"); + drawable.animationState.clearTracks(); + if (oldSkin != null) drawable.skeleton.setSkin(oldSkin); + drawable.skeleton.setToSetupPose(); + drawable.update(0); + customSkin.dispose(); + return Bounds(minX, minY, maxX - minX, maxY - minY); + } +} + +/// A [StatefulWidget] to display a Spine skeleton. The skeleton can be loaded from an asset bundle ([SpineWidget.fromAsset], +/// local files [SpineWidget.fromFile], URLs [SpineWidget.fromHttp], or a pre-loaded [SkeletonDrawable] ([SpineWidget.fromDrawable]). +/// +/// The skeleton displayed by a `SpineWidget` can be controlled via a [SpineWidgetController]. +/// +/// The size of the widget can be derived from the bounds provided by a [BoundsProvider]. If the widget is not sized by the bounds +/// computed by the [BoundsProvider], the widget will use the computed bounds to fit the skeleton inside the widget's dimensions. +class SpineWidget extends StatefulWidget { + final _AssetType _assetType; + final AssetBundle? _bundle; + final String? _skeletonFile; + final String? _atlasFile; + final SkeletonDrawable? _drawable; + final SpineWidgetController _controller; + final BoxFit _fit; + final Alignment _alignment; + final BoundsProvider _boundsProvider; + final bool _sizedByBounds; + + /// Constructs a new [SpineWidget] from files in the root bundle or the optionally specified [bundle]. The [_atlasFile] specifies the + /// `.atlas` file to be loaded for the images used to render the skeleton. The [_skeletonFile] specifies either a Skeleton `.json` or + /// `.skel` file containing the skeleton data. + /// + /// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow + /// modifying how the skeleton inside the widget is animated and rendered. + /// + /// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton + /// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider + /// are used. + /// + /// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds]. + SpineWidget.fromAsset(this._atlasFile, this._skeletonFile, this._controller, + {AssetBundle? bundle, BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key}) + : _assetType = _AssetType.asset, + _fit = fit ?? BoxFit.contain, + _alignment = alignment ?? Alignment.center, + _boundsProvider = boundsProvider ?? const SetupPoseBounds(), + _sizedByBounds = sizedByBounds ?? false, + _drawable = null, + _bundle = bundle ?? rootBundle; + + /// Constructs a new [SpineWidget] from files. The [_atlasFile] specifies the `.atlas` file to be loaded for the images used to render + /// the skeleton. The [_skeletonFile] specifies either a Skeleton `.json` or `.skel` file containing the skeleton data. + /// + /// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow + /// modifying how the skeleton inside the widget is animated and rendered. + /// + /// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton + /// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider + /// are used. + /// + /// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds]. + const SpineWidget.fromFile(this._atlasFile, this._skeletonFile, this._controller, + {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key}) + : _assetType = _AssetType.file, + _bundle = null, + _fit = fit ?? BoxFit.contain, + _alignment = alignment ?? Alignment.center, + _boundsProvider = boundsProvider ?? const SetupPoseBounds(), + _sizedByBounds = sizedByBounds ?? false, + _drawable = null; + + /// Constructs a new [SpineWidget] from HTTP URLs. The [_atlasFile] specifies the `.atlas` file to be loaded for the images used to render + /// the skeleton. The [_skeletonFile] specifies either a Skeleton `.json` or `.skel` file containing the skeleton data. + /// + /// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow + /// modifying how the skeleton inside the widget is animated and rendered. + /// + /// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton + /// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider + /// are used. + /// + /// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds]. + const SpineWidget.fromHttp(this._atlasFile, this._skeletonFile, this._controller, + {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key}) + : _assetType = _AssetType.http, + _bundle = null, + _fit = fit ?? BoxFit.contain, + _alignment = alignment ?? Alignment.center, + _boundsProvider = boundsProvider ?? const SetupPoseBounds(), + _sizedByBounds = sizedByBounds ?? false, + _drawable = null; + + /// Constructs a new [SpineWidget] from a [SkeletonDrawable]. + /// + /// After initialization is complete, the provided [_controller] is invoked as per the [SpineWidgetController] semantics, to allow + /// modifying how the skeleton inside the widget is animated and rendered. + /// + /// The skeleton is fitted and aligned inside the widget as per the [fit] and [alignment] arguments. For this purpose, the skeleton + /// bounds must be computed via a [BoundsProvider]. By default, [BoxFit.contain], [Alignment.center], and a [SetupPoseBounds] provider + /// are used. + /// + /// The widget can optionally by sized by the bounds provided by the [BoundsProvider] by passing `true` for [sizedByBounds]. + const SpineWidget.fromDrawable(this._drawable, this._controller, + {BoxFit? fit, Alignment? alignment, BoundsProvider? boundsProvider, bool? sizedByBounds, super.key}) + : _assetType = _AssetType.drawable, + _bundle = null, + _fit = fit ?? BoxFit.contain, + _alignment = alignment ?? Alignment.center, + _boundsProvider = boundsProvider ?? const SetupPoseBounds(), + _sizedByBounds = sizedByBounds ?? false, + _skeletonFile = null, + _atlasFile = null; + + @override + State createState() => _SpineWidgetState(); +} + +class _SpineWidgetState extends State { + late Bounds _computedBounds; + SkeletonDrawable? _drawable; + + @override + void initState() { + super.initState(); + if (widget._assetType == _AssetType.drawable) { + loadDrawable(widget._drawable!); + } else { + loadFromAsset(widget._bundle, widget._atlasFile!, widget._skeletonFile!, widget._assetType); + } + } + + void loadDrawable(SkeletonDrawable drawable) { + _drawable = drawable; + _computedBounds = widget._boundsProvider.computeBounds(drawable); + widget._controller._initialize(drawable); + setState(() {}); + } + + void loadFromAsset(AssetBundle? bundle, String atlasFile, String skeletonFile, _AssetType assetType) async { + switch (assetType) { + case _AssetType.asset: + loadDrawable(await SkeletonDrawable.fromAsset(atlasFile, skeletonFile, bundle: bundle)); + break; + case _AssetType.file: + loadDrawable(await SkeletonDrawable.fromFile(atlasFile, skeletonFile)); + break; + case _AssetType.http: + loadDrawable(await SkeletonDrawable.fromHttp(atlasFile, skeletonFile)); + break; + case _AssetType.drawable: + throw Exception("Drawable can not be loaded via loadFromAsset()."); + } + } + + @override + Widget build(BuildContext context) { + if (_drawable != null) { + return _SpineRenderObjectWidget( + _drawable!, widget._controller, widget._fit, widget._alignment, _computedBounds, widget._sizedByBounds); + } else { + return const SizedBox(); + } + } + + @override + void dispose() { + super.dispose(); + widget._controller._drawable?.dispose(); + } +} + +class _SpineRenderObjectWidget extends LeafRenderObjectWidget { + final SkeletonDrawable _skeletonDrawable; + final SpineWidgetController _controller; + final BoxFit _fit; + final Alignment _alignment; + final Bounds _bounds; + final bool _sizedByBounds; + + const _SpineRenderObjectWidget(this._skeletonDrawable, this._controller, this._fit, this._alignment, this._bounds, this._sizedByBounds); + + @override + RenderObject createRenderObject(BuildContext context) { + return _SpineRenderObject(_skeletonDrawable, _controller, _fit, _alignment, _bounds, _sizedByBounds); + } + + @override + void updateRenderObject(BuildContext context, covariant _SpineRenderObject renderObject) { + renderObject.skeletonDrawable = _skeletonDrawable; + renderObject.fit = _fit; + renderObject.alignment = _alignment; + renderObject.bounds = _bounds; + renderObject.sizedByBounds = _sizedByBounds; + } +} + +class _SpineRenderObject extends RenderBox { + SkeletonDrawable _skeletonDrawable; + final SpineWidgetController _controller; + double _deltaTime = 0; + final Stopwatch _stopwatch = Stopwatch(); + BoxFit _fit; + Alignment _alignment; + Bounds _bounds; + bool _sizedByBounds; + bool _disposed = false; + + _SpineRenderObject(this._skeletonDrawable, this._controller, this._fit, this._alignment, this._bounds, this._sizedByBounds); + + set skeletonDrawable(SkeletonDrawable skeletonDrawable) { + if (_skeletonDrawable == skeletonDrawable) return; + + _skeletonDrawable = skeletonDrawable; + markNeedsLayout(); + markNeedsPaint(); + } + + BoxFit get fit => _fit; + + set fit(BoxFit fit) { + if (fit != _fit) { + _fit = fit; + markNeedsLayout(); + markNeedsPaint(); + } + } + + Alignment get alignment => _alignment; + + set alignment(Alignment alignment) { + if (alignment != _alignment) { + _alignment = alignment; + markNeedsLayout(); + markNeedsPaint(); + } + } + + Bounds get bounds => _bounds; + + set bounds(Bounds bounds) { + if (bounds != _bounds) { + _bounds = bounds; + markNeedsLayout(); + markNeedsPaint(); + } + } + + bool get sizedByBounds => _sizedByBounds; + + set sizedByBounds(bool sizedByBounds) { + if (sizedByBounds != _sizedByBounds) { + _sizedByBounds = _sizedByBounds; + markNeedsLayout(); + markNeedsPaint(); + } + } + + @override + bool get sizedByParent => !_sizedByBounds; + + @override + bool get isRepaintBoundary => true; + + @override + bool hitTestSelf(Offset position) => true; + + @override + double computeMinIntrinsicWidth(double height) { + return _computeConstrainedSize(BoxConstraints.tightForFinite(height: height)).width; + } + + @override + double computeMaxIntrinsicWidth(double height) { + return _computeConstrainedSize(BoxConstraints.tightForFinite(height: height)).width; + } + + @override + double computeMinIntrinsicHeight(double width) { + return _computeConstrainedSize(BoxConstraints.tightForFinite(width: width)).height; + } + + @override + double computeMaxIntrinsicHeight(double width) { + return _computeConstrainedSize(BoxConstraints.tightForFinite(width: width)).height; + } + + // Called when not sizedByParent, uses the intrinsic width/height for sizing, while trying to retain aspect ratio. + @override + void performLayout() { + if (!sizedByParent) size = _computeConstrainedSize(constraints); + } + + // Called when sizedByParent, we want to go as big as possible. + @override + void performResize() { + size = constraints.biggest; + } + + Size _computeConstrainedSize(BoxConstraints constraints) { + return sizedByParent + ? constraints.smallest + : constraints.constrainSizeAndAttemptToPreserveAspectRatio(Size(_bounds.width, _bounds.height)); + } + + @override + void attach(rendering.PipelineOwner owner) { + super.attach(owner); + _stopwatch.start(); + SchedulerBinding.instance.scheduleFrameCallback(_beginFrame); + _controller._setRenderObject(this); + } + + @override + void detach() { + _stopwatch.stop(); + super.detach(); + _controller._setRenderObject(null); + } + + @override + void dispose() { + super.dispose(); + _disposed = true; + } + + void _scheduleFrame() { + SchedulerBinding.instance.scheduleFrameCallback(_beginFrame); + } + + void _beginFrame(Duration duration) { + if (_disposed) return; + _deltaTime = _stopwatch.elapsedTicks / _stopwatch.frequency; + _stopwatch.reset(); + _stopwatch.start(); + if (_controller.isPlaying) { + _controller.onBeforeUpdateWorldTransforms?.call(_controller); + _skeletonDrawable.update(_deltaTime); + _controller.onAfterUpdateWorldTransforms?.call(_controller); + markNeedsPaint(); + _scheduleFrame(); + } + } + + void _setCanvasTransform(Canvas canvas, Offset offset) { + final double x = -_bounds.x - _bounds.width / 2.0 - (_alignment.x * _bounds.width / 2.0); + final double y = -_bounds.y - _bounds.height / 2.0 - (_alignment.y * _bounds.height / 2.0); + double scaleX = 1.0, scaleY = 1.0; + + switch (_fit) { + case BoxFit.fill: + scaleX = size.width / _bounds.width; + scaleY = size.height / _bounds.height; + break; + case BoxFit.contain: + scaleX = scaleY = min(size.width / _bounds.width, size.height / _bounds.height); + break; + case BoxFit.cover: + scaleX = scaleY = max(size.width / _bounds.width, size.height / _bounds.height); + break; + case BoxFit.fitHeight: + scaleX = scaleY = size.height / _bounds.height; + break; + case BoxFit.fitWidth: + scaleX = scaleY = size.width / _bounds.width; + break; + case BoxFit.none: + scaleX = scaleY = 1.0; + break; + case BoxFit.scaleDown: + final double scale = min(size.width / _bounds.width, size.height / _bounds.height); + scaleX = scaleY = scale < 1.0 ? scale : 1.0; + break; + } + + var offsetX = offset.dx + size.width / 2.0 + (_alignment.x * size.width / 2.0); + var offsetY = offset.dy + size.height / 2.0 + (_alignment.y * size.height / 2.0); + canvas + ..translate(offsetX, offsetY) + ..scale(scaleX, scaleY) + ..translate(x, y); + _controller._setCoordinateTransform(x + offsetX / scaleY, y + offsetY / scaleY, scaleX, scaleY); + } + + @override + void paint(PaintingContext context, Offset offset) { + final Canvas canvas = context.canvas + ..save() + ..clipRect(offset & size); + + canvas.save(); + _setCanvasTransform(canvas, offset); + + _controller.onBeforePaint?.call(_controller, canvas); + var commands = _skeletonDrawable.render(); + for (final cmd in commands) { + canvas.drawVertices(cmd.vertices, rendering.BlendMode.modulate, _skeletonDrawable.atlas.atlasPagePaints[cmd.atlasPageIndex]); + } + _controller.onAfterPaint?.call(_controller, canvas, commands); + + canvas.restore(); + } +} diff --git a/spine-flutter/linux/CMakeLists.txt b/spine-flutter/linux/CMakeLists.txt new file mode 100644 index 000000000..b42273991 --- /dev/null +++ b/spine-flutter/linux/CMakeLists.txt @@ -0,0 +1,22 @@ +# The Flutter tooling requires that developers have CMake 3.10 or later +# installed. You should not increase this version, as doing so will cause +# the plugin to fail to compile for some customers of the plugin. +cmake_minimum_required(VERSION 3.10) + +# Project-level configuration. +set(PROJECT_NAME "spine_flutter") +project(${PROJECT_NAME} LANGUAGES CXX) + +# Invoke the build for native code shared with the other target platforms. +# This can be changed to accomodate different builds. +add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared") + +# List of absolute paths to libraries that should be bundled with the plugin. +# This list could contain prebuilt libraries, or libraries created by an +# external build triggered from this build file. +set(spine_flutter_bundled_libraries + # Defined in ../src/CMakeLists.txt. + # This can be changed to accomodate different builds. + $ + PARENT_SCOPE +) diff --git a/spine-flutter/macos/Classes/spine_flutter.cpp b/spine-flutter/macos/Classes/spine_flutter.cpp new file mode 100644 index 000000000..ac5716e5d --- /dev/null +++ b/spine-flutter/macos/Classes/spine_flutter.cpp @@ -0,0 +1,3 @@ +// Relative import to be able to reuse the C sources. +// See the comment in ../{projectName}}.podspec for more information. +#include "../../src/spine_flutter.cpp" diff --git a/spine-flutter/macos/spine_flutter.podspec b/spine-flutter/macos/spine_flutter.podspec new file mode 100644 index 000000000..931b9f54f --- /dev/null +++ b/spine-flutter/macos/spine_flutter.podspec @@ -0,0 +1,28 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint spine_flutter.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'spine_flutter' + s.version = '0.0.1' + s.summary = 'A new Flutter FFI plugin project.' + s.description = <<-DESC +A new Flutter FFI plugin project. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + + # This will ensure the source files in Classes/ are included in the native + # builds of apps using this FFI plugin. Podspec does not support relative + # paths, so Classes contains a forwarder C file that relatively imports + # `../src/*` so that the C sources can be shared among all target platforms. + s.source = { :path => '.' } + s.source_files = 'Classes/**/*.{cpp}' + s.xcconfig = { 'HEADER_SEARCH_PATHS' => '"' + __dir__ + '/Classes/spine-cpp/include"' } + s.dependency 'FlutterMacOS' + + s.platform = :osx, '10.11' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' +end diff --git a/spine-flutter/pubspec.yaml b/spine-flutter/pubspec.yaml new file mode 100644 index 000000000..64128e3aa --- /dev/null +++ b/spine-flutter/pubspec.yaml @@ -0,0 +1,48 @@ +name: spine_flutter +description: The official Spine Flutter Runtime to load, display and interact with Spine animations. +version: 4.2.11 +homepage: https://esotericsoftware.com +repository: https://github.com/esotericsoftware/spine-runtimes +issue_tracker: https://github.com/esotericsoftware/spine-runtimes/issues +documentation: https://esotericsoftware.com/spine-flutter + +environment: + sdk: ">=2.17.6 <3.0.0" + flutter: ">=3.7.0" + +dependencies: + flutter: + sdk: flutter + ffi: ^2.0.1 + web_ffi_fork: ^0.7.4 + inject_js: ^2.0.0 + js: ^0.6.3 + meta: ^1.3.0 + http: ^0.13.5 + path: ^1.8.2 + raw_image_provider: ^0.2.0 + +dev_dependencies: + ffigen: ^6.1.2 + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + +flutter: + plugin: + platforms: + android: + ffiPlugin: true + ios: + ffiPlugin: true + linux: + ffiPlugin: true + macos: + ffiPlugin: true + windows: + ffiPlugin: true + web: + + assets: + - lib/assets/libspine_flutter.js + - lib/assets/libspine_flutter.wasm diff --git a/spine-flutter/setup.sh b/spine-flutter/setup.sh new file mode 100755 index 000000000..d3bc20e7c --- /dev/null +++ b/spine-flutter/setup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +pushd $dir > /dev/null +# Need to copy spine-cpp sources to the ios and macos folders, as CocoaPods requires +# all source files to be under the same folder hierarchy the podspec file resides in. +cp -r ../spine-cpp/spine-cpp ios/Classes +cp -r ../spine-cpp/spine-cpp macos/Classes +cp -r ../spine-cpp/spine-cpp src +popd \ No newline at end of file diff --git a/spine-flutter/src/CMakeLists.txt b/spine-flutter/src/CMakeLists.txt new file mode 100644 index 000000000..2ef603602 --- /dev/null +++ b/spine-flutter/src/CMakeLists.txt @@ -0,0 +1,28 @@ +# The Flutter tooling requires that developers have CMake 3.10 or later +# installed. You should not increase this version, as doing so will cause +# the plugin to fail to compile for some customers of the plugin. +cmake_minimum_required(VERSION 3.10) + +project(pine_flutter_library VERSION 0.0.1) + +file(GLOB SPINE_SOURCES "spine-cpp/src/**/*.cpp") + +add_library(spine_flutter SHARED + "spine_flutter.cpp" + ${SPINE_SOURCES} +) + +set_target_properties(spine_flutter PROPERTIES + PUBLIC_HEADER spine_flutter.h + OUTPUT_NAME "spine_flutter" +) +target_include_directories(spine_flutter PUBLIC spine-cpp/include) +target_compile_definitions(spine_flutter PUBLIC DART_SHARED_LIB) + +if(${SPINE_FLUTTER_TESTBED}) +set (CMAKE_CXX_STANDARD 11) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize=undefined") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=undefined") +add_executable(spine_flutter_test main.cpp spine_flutter.cpp ${SPINE_SOURCES}) +include_directories(spine_flutter_test PUBLIC spine-cpp/include) +endif() \ No newline at end of file diff --git a/spine-flutter/src/spine_flutter.cpp b/spine-flutter/src/spine_flutter.cpp new file mode 100644 index 000000000..a970f6437 --- /dev/null +++ b/spine-flutter/src/spine_flutter.cpp @@ -0,0 +1,4163 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated September 24, 2021. Replaces all prior versions. + * + * Copyright (c) 2013-2021, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include "spine_flutter.h" +#include +#include +#include + +using namespace spine; + +struct Block { + int size; + int allocated; + uint8_t *memory; + + int free() { + return size - allocated; + } + + bool canFit(int numBytes) { + return free() >= numBytes; + } + + uint8_t *allocate(int numBytes) { + uint8_t *ptr = memory + allocated; + allocated += numBytes; + return ptr; + } +}; + +class BlockAllocator : public SpineObject { + int initialBlockSize; + Vector blocks; + +public: + BlockAllocator(int initialBlockSize) : initialBlockSize(initialBlockSize) { + blocks.add(newBlock(initialBlockSize)); + } + + ~BlockAllocator() { + for (int i = 0; i < blocks.size(); i++) { + SpineExtension::free(blocks[i].memory, __FILE__, __LINE__); + } + } + + Block newBlock(int numBytes) { + Block block = {MathUtil::max(initialBlockSize, numBytes), 0, nullptr}; + block.memory = SpineExtension::alloc(block.size, __FILE__, __LINE__); + return block; + } + + template + T *allocate(size_t num) { + return (T *) _allocate((int) (sizeof(T) * num)); + } + + void compress() { + int totalSize = 0; + for (int i = 0; i < blocks.size(); i++) { + totalSize += blocks[i].size; + SpineExtension::free(blocks[i].memory, __FILE__, __LINE__); + } + blocks.clear(); + blocks.add(newBlock(totalSize)); + } + +private: + void *_allocate(int numBytes) { + // 16-byte align allocations + int alignedNumBytes = numBytes + (numBytes % 16 != 0 ? 16 - (numBytes % 16) : 0); + Block *block = &blocks[blocks.size() - 1]; + if (!block->canFit(alignedNumBytes)) { + blocks.add(newBlock(MathUtil::max(initialBlockSize, alignedNumBytes))); + block = &blocks[blocks.size() - 1]; + } + return block->allocate(alignedNumBytes); + } +}; + +struct AnimationStateEvent { + EventType type; + TrackEntry *entry; + Event *event; + AnimationStateEvent(EventType type, TrackEntry *entry, Event *event) : type(type), entry(entry), event(event){}; +}; + +struct EventListener : public AnimationStateListenerObject { + Vector events; + + void callback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) { + events.add(AnimationStateEvent(type, entry, event)); + } +}; + +typedef struct _spine_atlas { + void *atlas; + utf8 **imagePaths; + int32_t numImagePaths; + utf8 *error; +} _spine_atlas; + +typedef struct _spine_skeleton_data_result { + spine_skeleton_data skeletonData; + utf8 *error; +} _spine_skeleton_data_result; + +typedef struct _spine_render_command { + float *positions; + float *uvs; + int32_t *colors; + int32_t numVertices; + uint16_t *indices; + int32_t numIndices; + int32_t atlasPage; + spine_blend_mode blendMode; + struct _spine_render_command *next; +} _spine_render_command; + +typedef struct _spine_bounds { + float x, y, width, height; +} _spine_bounds; + +typedef struct _spine_vector { + float x, y; +} _spine_vector; + +typedef struct _spine_skeleton_drawable : public SpineObject { + spine_skeleton skeleton; + spine_animation_state animationState; + spine_animation_state_data animationStateData; + spine_animation_state_events animationStateEvents; + void *clipping; + BlockAllocator *allocator; + Vector worldVertices; + Vector quadIndices; + Vector<_spine_render_command *> renderCommands; + + _spine_skeleton_drawable() { + quadIndices.add(0); + quadIndices.add(1); + quadIndices.add(2); + quadIndices.add(2); + quadIndices.add(3); + quadIndices.add(0); + } +} _spine_skeleton_drawable; + +typedef struct _spine_skin_entry { + int32_t slotIndex; + utf8 *name; + spine_attachment attachment; +} _spine_skin_entry; + +typedef struct _spine_skin_entries { + int32_t numEntries; + _spine_skin_entry *entries; +} _spine_skin_entries; + +static Color NULL_COLOR(0, 0, 0, 0); + +static SpineExtension *defaultExtension = nullptr; +static DebugExtension *debugExtension = nullptr; + +static void initExtensions() { + if (defaultExtension == nullptr) { + defaultExtension = new DefaultSpineExtension(); + debugExtension = new DebugExtension(defaultExtension); + } +} + +spine::SpineExtension *spine::getDefaultExtension() { + initExtensions(); + return defaultExtension; +} + +void spine_enable_debug_extension(int32_t enable) { + initExtensions(); + SpineExtension::setInstance(enable ? debugExtension : defaultExtension); +} + +int32_t spine_major_version() { + return SPINE_MAJOR_VERSION; +} + +int32_t spine_minor_version() { + return SPINE_MINOR_VERSION; +} + +void spine_report_leaks() { + initExtensions(); + debugExtension->reportLeaks(); + fflush(stdout); +} + +// Color + +float spine_color_get_r(spine_color color) { + if (!color) return 0; + return ((Color *) color)->r; +} + +float spine_color_get_g(spine_color color) { + if (!color) return 0; + return ((Color *) color)->g; +} + +float spine_color_get_b(spine_color color) { + if (!color) return 0; + return ((Color *) color)->b; +} + +float spine_color_get_a(spine_color color) { + if (!color) return 0; + return ((Color *) color)->a; +} + +// Bounds + +float spine_bounds_get_x(spine_bounds bounds) { + if (!bounds) return 0; + return ((_spine_bounds *) bounds)->x; +} + +float spine_bounds_get_y(spine_bounds bounds) { + if (!bounds) return 0; + return ((_spine_bounds *) bounds)->y; +} + +float spine_bounds_get_width(spine_bounds bounds) { + if (!bounds) return 0; + return ((_spine_bounds *) bounds)->width; +} + +float spine_bounds_get_height(spine_bounds bounds) { + if (!bounds) return 0; + return ((_spine_bounds *) bounds)->height; +} + +// Vector +float spine_vector_get_x(spine_vector vector) { + if (!vector) return 0; + return ((_spine_vector *) vector)->x; +} + +float spine_vector_get_y(spine_vector vector) { + if (!vector) return 0; + return ((_spine_vector *) vector)->y; +} + +// Atlas + +spine_atlas spine_atlas_load(const utf8 *atlasData) { + if (!atlasData) return nullptr; + int32_t length = (int32_t) strlen(atlasData); + auto atlas = new (__FILE__, __LINE__) Atlas(atlasData, length, "", (TextureLoader *) nullptr, false); + _spine_atlas *result = SpineExtension::calloc<_spine_atlas>(1, __FILE__, __LINE__); + result->atlas = atlas; + result->numImagePaths = (int32_t) atlas->getPages().size(); + result->imagePaths = SpineExtension::calloc(result->numImagePaths, __FILE__, __LINE__); + for (int i = 0; i < result->numImagePaths; i++) { + result->imagePaths[i] = (utf8 *) strdup(atlas->getPages()[i]->texturePath.buffer()); + } + return (spine_atlas) result; +} + +int32_t spine_atlas_get_num_image_paths(spine_atlas atlas) { + if (!atlas) return 0; + return ((_spine_atlas *) atlas)->numImagePaths; +} + +utf8 *spine_atlas_get_image_path(spine_atlas atlas, int32_t index) { + if (!atlas) return nullptr; + return ((_spine_atlas *) atlas)->imagePaths[index]; +} + +utf8 *spine_atlas_get_error(spine_atlas atlas) { + if (!atlas) return nullptr; + return ((_spine_atlas *) atlas)->error; +} + +void spine_atlas_dispose(spine_atlas atlas) { + if (!atlas) return; + _spine_atlas *_atlas = (_spine_atlas *) atlas; + if (_atlas->atlas) delete (Atlas *) _atlas->atlas; + if (_atlas->error) free(_atlas->error); + for (int i = 0; i < _atlas->numImagePaths; i++) { + free(_atlas->imagePaths[i]); + } + SpineExtension::free(_atlas->imagePaths, __FILE__, __LINE__); + SpineExtension::free(_atlas, __FILE__, __LINE__); +} + +// SkeletonData + +spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const utf8 *skeletonData) { + _spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__); + _spine_atlas *_atlas = (_spine_atlas *) atlas; + Bone::setYDown(true); + if (!_atlas) return (spine_skeleton_data_result) result; + if (!_atlas->atlas) return (spine_skeleton_data_result) result; + if (!skeletonData) return (spine_skeleton_data_result) result; + SkeletonJson json((Atlas *) _atlas->atlas); + SkeletonData *data = json.readSkeletonData(skeletonData); + result->skeletonData = (spine_skeleton_data) data; + if (!json.getError().isEmpty()) { + result->error = (utf8 *) strdup(json.getError().buffer()); + } + return (spine_skeleton_data_result) result; +} + +spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length) { + _spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__); + _spine_atlas *_atlas = (_spine_atlas *) atlas; + Bone::setYDown(true); + if (!_atlas) return (spine_skeleton_data_result) result; + if (!_atlas->atlas) return (spine_skeleton_data_result) result; + if (!skeletonData) return (spine_skeleton_data_result) result; + if (length <= 0) return (spine_skeleton_data_result) result; + SkeletonBinary binary((Atlas *) _atlas->atlas); + SkeletonData *data = binary.readSkeletonData(skeletonData, length); + result->skeletonData = (spine_skeleton_data) data; + if (!binary.getError().isEmpty()) { + result->error = (utf8 *) strdup(binary.getError().buffer()); + } + return (spine_skeleton_data_result) result; +} + +utf8 *spine_skeleton_data_result_get_error(spine_skeleton_data_result result) { + if (!result) return nullptr; + return ((_spine_skeleton_data_result *) result)->error; +} +spine_skeleton_data spine_skeleton_data_result_get_data(spine_skeleton_data_result result) { + if (!result) return nullptr; + return ((_spine_skeleton_data_result *) result)->skeletonData; +} + +void spine_skeleton_data_result_dispose(spine_skeleton_data_result result) { + if (!result) return; + _spine_skeleton_data_result *_result = (_spine_skeleton_data_result *) result; + if (_result->error) SpineExtension::free(_result->error, __FILE__, __LINE__); + SpineExtension::free(_result, __FILE__, __LINE__); +} + +spine_bone_data spine_skeleton_data_find_bone(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_bone_data) _data->findBone(name); +} + +spine_slot_data spine_skeleton_data_find_slot(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_slot_data) _data->findSlot(name); +} + +spine_skin spine_skeleton_data_find_skin(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_skin) _data->findSkin(name); +} + +spine_event_data spine_skeleton_data_find_event(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_event_data) _data->findEvent(name); +} + +spine_animation spine_skeleton_data_find_animation(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_animation) _data->findAnimation(name); +} + +spine_ik_constraint_data spine_skeleton_data_find_ik_constraint(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_ik_constraint_data) _data->findIkConstraint(name); +} + +spine_transform_constraint_data spine_skeleton_data_find_transform_constraint(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_transform_constraint_data) _data->findTransformConstraint(name); +} + +spine_path_constraint_data spine_skeleton_data_find_path_constraint(spine_skeleton_data data, const utf8 *name) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_path_constraint_data) _data->findPathConstraint(name); +} + +const utf8 *spine_skeleton_data_get_name(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (utf8 *) _data->getName().buffer(); +} + +int32_t spine_skeleton_data_get_num_bones(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getBones().size(); +} + +spine_bone_data *spine_skeleton_data_get_bones(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_bone_data *) _data->getBones().buffer(); +} + +int32_t spine_skeleton_data_get_num_slots(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getSlots().size(); +} + +spine_slot_data *spine_skeleton_data_get_slots(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_slot_data *) _data->getSlots().buffer(); +} + +int32_t spine_skeleton_data_get_num_skins(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getSkins().size(); +} + +spine_skin *spine_skeleton_data_get_skins(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_skin *) _data->getSkins().buffer(); +} + +spine_skin spine_skeleton_data_get_default_skin(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_skin) _data->getDefaultSkin(); +} + +void spine_skeleton_data_set_default_skin(spine_skeleton_data data, spine_skin skin) { + if (data == nullptr) return; + SkeletonData *_data = (SkeletonData *) data; + _data->setDefaultSkin((Skin *) skin); +} + +int32_t spine_skeleton_data_get_num_events(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getEvents().size(); +} + +spine_event_data *spine_skeleton_data_get_events(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_event_data *) _data->getEvents().buffer(); +} + +int32_t spine_skeleton_data_get_num_animations(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getAnimations().size(); +} + +spine_animation *spine_skeleton_data_get_animations(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_animation *) _data->getAnimations().buffer(); +} + +int32_t spine_skeleton_data_get_num_ik_constraints(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getIkConstraints().size(); +} + +spine_ik_constraint_data *spine_skeleton_data_get_ik_constraints(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_ik_constraint_data *) _data->getIkConstraints().buffer(); +} + +int32_t spine_skeleton_data_get_num_transform_constraints(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getTransformConstraints().size(); +} + +spine_transform_constraint_data *spine_skeleton_data_get_transform_constraints(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_transform_constraint_data *) _data->getTransformConstraints().buffer(); +} + +int32_t spine_skeleton_data_get_num_path_constraints(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return (int32_t) _data->getPathConstraints().size(); +} + +spine_path_constraint_data *spine_skeleton_data_get_path_constraints(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (spine_path_constraint_data *) _data->getPathConstraints().buffer(); +} + +float spine_skeleton_data_get_x(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return _data->getX(); +} + +void spine_skeleton_data_set_x(spine_skeleton_data data, float x) { + if (data == nullptr) return; + SkeletonData *_data = (SkeletonData *) data; + _data->setX(x); +} + +float spine_skeleton_data_get_y(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return _data->getY(); +} + +void spine_skeleton_data_set_y(spine_skeleton_data data, float y) { + if (data == nullptr) return; + SkeletonData *_data = (SkeletonData *) data; + _data->setY(y); +} + +float spine_skeleton_data_get_width(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return _data->getWidth(); +} + +void spine_skeleton_data_set_width(spine_skeleton_data data, float width) { + if (data == nullptr) return; + SkeletonData *_data = (SkeletonData *) data; + _data->setWidth(width); +} + +float spine_skeleton_data_get_height(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return _data->getHeight(); +} + +void spine_skeleton_data_set_height(spine_skeleton_data data, float height) { + if (data == nullptr) return; + SkeletonData *_data = (SkeletonData *) data; + _data->setHeight(height); +} + +const utf8 *spine_skeleton_data_get_version(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (utf8 *) _data->getVersion().buffer(); +} + +const utf8 *spine_skeleton_data_get_hash(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (utf8 *) _data->getHash().buffer(); +} + +const utf8 *spine_skeleton_data_get_images_path(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (utf8 *) _data->getImagesPath().buffer(); +} + +const utf8 *spine_skeleton_data_get_audio_path(spine_skeleton_data data) { + if (data == nullptr) return nullptr; + SkeletonData *_data = (SkeletonData *) data; + return (utf8 *) _data->getAudioPath().buffer(); +} + +float spine_skeleton_data_get_fps(spine_skeleton_data data) { + if (data == nullptr) return 0; + SkeletonData *_data = (SkeletonData *) data; + return _data->getFps(); +} + +void spine_skeleton_data_dispose(spine_skeleton_data data) { + if (!data) return; + delete (SkeletonData *) data; +} + +// RenderCommand +static _spine_render_command *spine_render_command_create(BlockAllocator &allocator, int numVertices, int32_t numIndices, spine_blend_mode blendMode, int32_t pageIndex) { + _spine_render_command *cmd = allocator.allocate<_spine_render_command>(1); + cmd->positions = allocator.allocate(numVertices << 1); + cmd->uvs = allocator.allocate(numVertices << 1); + cmd->colors = allocator.allocate(numVertices); + cmd->numVertices = numVertices; + cmd->indices = allocator.allocate(numIndices); + cmd->numIndices = numIndices; + cmd->blendMode = blendMode; + cmd->atlasPage = pageIndex; + cmd->next = nullptr; + return cmd; +} + +// SkeletonDrawable + +spine_skeleton_drawable spine_skeleton_drawable_create(spine_skeleton_data skeletonData) { + _spine_skeleton_drawable *drawable = new (__FILE__, __LINE__) _spine_skeleton_drawable(); + drawable->skeleton = (spine_skeleton) new (__FILE__, __LINE__) Skeleton((SkeletonData *) skeletonData); + AnimationStateData *stateData = new (__FILE__, __LINE__) AnimationStateData((SkeletonData *) skeletonData); + drawable->animationStateData = (spine_animation_state_data) stateData; + AnimationState *state = new (__FILE__, __LINE__) AnimationState(stateData); + drawable->animationState = (spine_animation_state) state; + state->setManualTrackEntryDisposal(true); + EventListener *listener = new EventListener(); + drawable->animationStateEvents = (spine_animation_state_events) listener; + state->setListener(listener); + drawable->clipping = new (__FILE__, __LINE__) SkeletonClipping(); + drawable->allocator = new (__FILE__, __LINE__) BlockAllocator(2048); + return (spine_skeleton_drawable) drawable; +} + +void spine_skeleton_drawable_dispose(spine_skeleton_drawable drawable) { + _spine_skeleton_drawable *_drawable = (_spine_skeleton_drawable *) drawable; + if (!_drawable) return; + if (_drawable->skeleton) delete (Skeleton *) _drawable->skeleton; + if (_drawable->animationState) delete (AnimationState *) _drawable->animationState; + if (_drawable->animationStateData) delete (AnimationStateData *) _drawable->animationStateData; + if (_drawable->animationStateEvents) delete (Vector *) (_drawable->animationStateEvents); + if (_drawable->clipping) delete (SkeletonClipping *) _drawable->clipping; + if (_drawable->allocator) delete (BlockAllocator *) _drawable->allocator; + SpineExtension::free(drawable, __FILE__, __LINE__); +} + +static _spine_render_command *batch_sub_commands(BlockAllocator &allocator, Vector<_spine_render_command *> &commands, int first, int last, int numVertices, int numIndices) { + _spine_render_command *batched = spine_render_command_create(allocator, numVertices, numIndices, commands[first]->blendMode, commands[first]->atlasPage); + float *positions = batched->positions; + float *uvs = batched->uvs; + int32_t *colors = batched->colors; + uint16_t *indices = batched->indices; + int indicesOffset = 0; + for (int i = first; i <= last; i++) { + _spine_render_command *cmd = commands[i]; + memcpy(positions, cmd->positions, sizeof(float) * 2 * cmd->numVertices); + memcpy(uvs, cmd->uvs, sizeof(float) * 2 * cmd->numVertices); + memcpy(colors, cmd->colors, sizeof(int32_t) * cmd->numVertices); + for (int ii = 0; ii < cmd->numIndices; ii++) + indices[ii] = cmd->indices[ii] + indicesOffset; + indicesOffset += cmd->numVertices; + positions += 2 * cmd->numVertices; + uvs += 2 * cmd->numVertices; + colors += cmd->numVertices; + indices += cmd->numIndices; + } + return batched; +} + +static _spine_render_command *batch_commands(BlockAllocator &allocator, Vector<_spine_render_command *> &commands) { + if (commands.size() == 0) return nullptr; + + _spine_render_command *root = nullptr; + _spine_render_command *last = nullptr; + + _spine_render_command *first = commands[0]; + int startIndex = 0; + int i = 1; + int numVertices = first->numVertices; + int numIndices = first->numIndices; + while (i <= commands.size()) { + _spine_render_command *cmd = i < commands.size() ? commands[i] : nullptr; + if (cmd != nullptr && cmd->atlasPage == first->atlasPage && + cmd->blendMode == first->blendMode && + numIndices + cmd->numIndices < 0xffff) { + numVertices += cmd->numVertices; + numIndices += cmd->numIndices; + } else { + _spine_render_command *batched = batch_sub_commands(allocator, commands, startIndex, i - 1, numVertices, numIndices); + if (!last) { + root = last = batched; + } else { + last->next = batched; + last = batched; + } + if (i == commands.size()) break; + first = commands[i]; + startIndex = i; + numVertices = first->numVertices; + numIndices = first->numIndices; + } + i++; + } + return root; +} + +spine_render_command spine_skeleton_drawable_render(spine_skeleton_drawable drawable) { + _spine_skeleton_drawable *_drawable = (_spine_skeleton_drawable *) drawable; + if (!_drawable) return nullptr; + if (!_drawable->skeleton) return nullptr; + + _drawable->allocator->compress(); + _drawable->renderCommands.clear(); + + SkeletonClipping &clipper = *(SkeletonClipping *) _drawable->clipping; + Skeleton *skeleton = (Skeleton *) _drawable->skeleton; + + for (unsigned i = 0; i < skeleton->getSlots().size(); ++i) { + Slot &slot = *skeleton->getDrawOrder()[i]; + Attachment *attachment = slot.getAttachment(); + if (!attachment) continue; + + // Early out if the slot color is 0 or the bone is not active + if (slot.getColor().a == 0 || !slot.getBone().isActive()) { + clipper.clipEnd(slot); + continue; + } + + Vector *worldVertices = &_drawable->worldVertices; + Vector *quadIndices = &_drawable->quadIndices; + Vector *vertices = worldVertices; + int32_t verticesCount; + Vector *uvs; + Vector *indices; + int32_t indicesCount; + Color *attachmentColor; + int32_t pageIndex; + + if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) { + RegionAttachment *regionAttachment = (RegionAttachment *) attachment; + attachmentColor = ®ionAttachment->getColor(); + + // Early out if the slot color is 0 + if (attachmentColor->a == 0) { + clipper.clipEnd(slot); + continue; + } + + worldVertices->setSize(8, 0); + regionAttachment->computeWorldVertices(slot, *worldVertices, 0, 2); + verticesCount = 4; + uvs = ®ionAttachment->getUVs(); + indices = quadIndices; + indicesCount = 6; + pageIndex = ((AtlasRegion *) regionAttachment->getRegion())->page->index; + + } else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) { + MeshAttachment *mesh = (MeshAttachment *) attachment; + attachmentColor = &mesh->getColor(); + + // Early out if the slot color is 0 + if (attachmentColor->a == 0) { + clipper.clipEnd(slot); + continue; + } + + worldVertices->setSize(mesh->getWorldVerticesLength(), 0); + mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices->buffer(), 0, 2); + verticesCount = (int32_t) (mesh->getWorldVerticesLength() >> 1); + uvs = &mesh->getUVs(); + indices = &mesh->getTriangles(); + indicesCount = (int32_t) indices->size(); + pageIndex = ((AtlasRegion *) mesh->getRegion())->page->index; + + } else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) { + ClippingAttachment *clip = (ClippingAttachment *) slot.getAttachment(); + clipper.clipStart(slot, clip); + continue; + } else + continue; + + uint8_t r = static_cast(skeleton->getColor().r * slot.getColor().r * attachmentColor->r * 255); + uint8_t g = static_cast(skeleton->getColor().g * slot.getColor().g * attachmentColor->g * 255); + uint8_t b = static_cast(skeleton->getColor().b * slot.getColor().b * attachmentColor->b * 255); + uint8_t a = static_cast(skeleton->getColor().a * slot.getColor().a * attachmentColor->a * 255); + uint32_t color = (a << 24) | (r << 16) | (g << 8) | b; + + if (clipper.isClipping()) { + clipper.clipTriangles(*worldVertices, *indices, *uvs, 2); + vertices = &clipper.getClippedVertices(); + verticesCount = (int32_t) (clipper.getClippedVertices().size() >> 1); + uvs = &clipper.getClippedUVs(); + indices = &clipper.getClippedTriangles(); + indicesCount = (int32_t) (clipper.getClippedTriangles().size()); + } + + _spine_render_command *cmd = spine_render_command_create(*_drawable->allocator, verticesCount, indicesCount, (spine_blend_mode) slot.getData().getBlendMode(), pageIndex); + _drawable->renderCommands.add(cmd); + memcpy(cmd->positions, vertices->buffer(), (verticesCount << 1) * sizeof(float)); + memcpy(cmd->uvs, uvs->buffer(), (verticesCount << 1) * sizeof(float)); + for (int ii = 0; ii < verticesCount; ii++) cmd->colors[ii] = color; + memcpy(cmd->indices, indices->buffer(), indices->size() * sizeof(uint16_t)); + clipper.clipEnd(slot); + } + clipper.clipEnd(); + + return (spine_render_command) batch_commands(*_drawable->allocator, _drawable->renderCommands); +} + +spine_skeleton spine_skeleton_drawable_get_skeleton(spine_skeleton_drawable drawable) { + if (!drawable) return nullptr; + return ((_spine_skeleton_drawable *) drawable)->skeleton; +} + +spine_animation_state spine_skeleton_drawable_get_animation_state(spine_skeleton_drawable drawable) { + if (!drawable) return nullptr; + return ((_spine_skeleton_drawable *) drawable)->animationState; +} + +spine_animation_state_data spine_skeleton_drawable_get_animation_state_data(spine_skeleton_drawable drawable) { + if (!drawable) return nullptr; + return ((_spine_skeleton_drawable *) drawable)->animationStateData; +} + +spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable) { + if (!drawable) return nullptr; + return ((_spine_skeleton_drawable *) drawable)->animationStateEvents; +} + +// Render command +float *spine_render_command_get_positions(spine_render_command command) { + if (!command) return nullptr; + return ((_spine_render_command *) command)->positions; +} + +float *spine_render_command_get_uvs(spine_render_command command) { + if (!command) return nullptr; + return ((_spine_render_command *) command)->uvs; +} + +int32_t *spine_render_command_get_colors(spine_render_command command) { + if (!command) return nullptr; + return ((_spine_render_command *) command)->colors; +} + +int32_t spine_render_command_get_num_vertices(spine_render_command command) { + if (!command) return 0; + return ((_spine_render_command *) command)->numVertices; +} + +uint16_t *spine_render_command_get_indices(spine_render_command command) { + if (!command) return nullptr; + return ((_spine_render_command *) command)->indices; +} + +int32_t spine_render_command_get_num_indices(spine_render_command command) { + if (!command) return 0; + return ((_spine_render_command *) command)->numIndices; +} + +int32_t spine_render_command_get_atlas_page(spine_render_command command) { + if (!command) return 0; + return ((_spine_render_command *) command)->atlasPage; +} + +spine_blend_mode spine_render_command_get_blend_mode(spine_render_command command) { + if (!command) return SPINE_BLEND_MODE_NORMAL; + return ((_spine_render_command *) command)->blendMode; +} + +spine_render_command spine_render_command_get_next(spine_render_command command) { + if (!command) return nullptr; + return (spine_render_command) ((_spine_render_command *) command)->next; +} + +// Animation + +const utf8 *spine_animation_get_name(spine_animation animation) { + if (animation == nullptr) return nullptr; + Animation *_animation = (Animation *) animation; + return (utf8 *) _animation->getName().buffer(); +} + +float spine_animation_get_duration(spine_animation animation) { + if (animation == nullptr) return 0; + Animation *_animation = (Animation *) animation; + return _animation->getDuration(); +} + +// AnimationStateData +spine_skeleton_data spine_animation_state_data_get_skeleton_data(spine_animation_state_data stateData) { + if (stateData == nullptr) return nullptr; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + return (spine_skeleton_data) _stateData->getSkeletonData(); +} + +float spine_animation_state_data_get_default_mix(spine_animation_state_data stateData) { + if (stateData == nullptr) return 0; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + return _stateData->getDefaultMix(); +} + +void spine_animation_state_data_set_default_mix(spine_animation_state_data stateData, float defaultMix) { + if (stateData == nullptr) return; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + _stateData->setDefaultMix(defaultMix); +} + +void spine_animation_state_data_set_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to, float duration) { + if (stateData == nullptr) return; + if (from == nullptr || to == nullptr) return; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + _stateData->setMix((Animation *) from, (Animation *) to, duration); +} + +float spine_animation_state_data_get_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to) { + if (stateData == nullptr) return 0; + if (from == nullptr || to == nullptr) return 0; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + return _stateData->getMix((Animation *) from, (Animation *) to); +} + +void spine_animation_state_data_set_mix_by_name(spine_animation_state_data stateData, const utf8 *fromName, const utf8 *toName, float duration) { + if (stateData == nullptr) return; + if (fromName == nullptr || toName == nullptr) return; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + _stateData->setMix(fromName, toName, duration); +} + +float spine_animation_state_data_get_mix_by_name(spine_animation_state_data stateData, const utf8 *fromName, const utf8 *toName) { + if (stateData == nullptr) return 0; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + Animation *from = _stateData->getSkeletonData()->findAnimation(fromName); + Animation *to = _stateData->getSkeletonData()->findAnimation(toName); + if (from == nullptr || to == nullptr) return 0; + return _stateData->getMix(from, to); +} + +void spine_animation_state_data_clear(spine_animation_state_data stateData) { + if (stateData == nullptr) return; + AnimationStateData *_stateData = (AnimationStateData *) stateData; + _stateData->clear(); +} + +// AnimationState +void spine_animation_state_update(spine_animation_state state, float delta) { + if (state == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->update(delta); +} + +void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry) { + if (state == nullptr) return; + if (entry == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->disposeTrackEntry((TrackEntry *) entry); +} + +void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton) { + if (state == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->apply(*(Skeleton *) skeleton); +} + +void spine_animation_state_clear_tracks(spine_animation_state state) { + if (state == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->clearTracks(); +} + +int32_t spine_animation_state_get_num_tracks(spine_animation_state state) { + if (state == nullptr) return 0; + AnimationState *_state = (AnimationState *) state; + return (int32_t) _state->getTracks().size(); +} + +void spine_animation_state_clear_track(spine_animation_state state, int32_t trackIndex) { + if (state == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->clearTrack(trackIndex); +} + +spine_track_entry spine_animation_state_set_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8 *animationName, int32_t loop) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->setAnimation(trackIndex, animationName, loop); +} + +spine_track_entry spine_animation_state_set_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->setAnimation(trackIndex, (Animation *) animation, loop); +} + +spine_track_entry spine_animation_state_add_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8 *animationName, int32_t loop, float delay) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->addAnimation(trackIndex, animationName, loop, delay); +} + +spine_track_entry spine_animation_state_add_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop, float delay) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->addAnimation(trackIndex, (Animation *) animation, loop, delay); +} + +spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->setEmptyAnimation(trackIndex, mixDuration); +} + +spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration, float delay) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->addEmptyAnimation(trackIndex, mixDuration, delay); +} + +void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration) { + if (state == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->setEmptyAnimations(mixDuration); +} + +spine_track_entry spine_animation_state_get_current(spine_animation_state state, int32_t trackIndex) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_track_entry) _state->getCurrent(trackIndex); +} + +spine_animation_state_data spine_animation_state_get_data(spine_animation_state state) { + if (state == nullptr) return nullptr; + AnimationState *_state = (AnimationState *) state; + return (spine_animation_state_data) _state->getData(); +} + +float spine_animation_state_get_time_scale(spine_animation_state state) { + if (state == nullptr) return 0; + AnimationState *_state = (AnimationState *) state; + return _state->getTimeScale(); +} + +void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale) { + if (state == nullptr) return; + AnimationState *_state = (AnimationState *) state; + _state->setTimeScale(timeScale); +} + +int32_t spine_animation_state_events_get_num_events(spine_animation_state_events events) { + if (events == nullptr) return 0; + EventListener *_events = (EventListener *) events; + return (int32_t) _events->events.size(); +} + +spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int32_t index) { + if (events == nullptr) return SPINE_EVENT_TYPE_DISPOSE; + if (index < 0) return SPINE_EVENT_TYPE_DISPOSE; + EventListener *_events = (EventListener *) events; + if (index >= _events->events.size()) return SPINE_EVENT_TYPE_DISPOSE; + return (spine_event_type) _events->events[index].type; +} + +spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int32_t index) { + if (events == nullptr) return nullptr; + EventListener *_events = (EventListener *) events; + if (index >= _events->events.size()) return nullptr; + return (spine_track_entry) _events->events[index].entry; +} + +spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int32_t index) { + if (events == nullptr) return nullptr; + EventListener *_events = (EventListener *) events; + if (index >= _events->events.size()) return nullptr; + return (spine_event) _events->events[index].event; +} + +void spine_animation_state_events_reset(spine_animation_state_events events) { + if (events == nullptr) return; + EventListener *_events = (EventListener *) events; + _events->events.clear(); +} + +// TrackEntry + +int32_t spine_track_entry_get_track_index(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getTrackIndex(); +} + +spine_animation spine_track_entry_get_animation(spine_track_entry entry) { + if (entry == nullptr) return nullptr; + TrackEntry *_entry = (TrackEntry *) entry; + return (spine_animation) _entry->getAnimation(); +} + +spine_track_entry spine_track_entry_get_previous(spine_track_entry entry) { + if (entry == nullptr) return nullptr; + TrackEntry *_entry = (TrackEntry *) entry; + return (spine_track_entry) _entry->getPrevious(); +} + +int32_t spine_track_entry_get_loop(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getLoop() ? -1 : 0; +} + +void spine_track_entry_set_loop(spine_track_entry entry, int32_t loop) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setLoop(loop); +} + +int32_t spine_track_entry_get_hold_previous(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getHoldPrevious() ? -1 : 0; +} + +void spine_track_entry_set_hold_previous(spine_track_entry entry, int32_t holdPrevious) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setHoldPrevious(holdPrevious); +} + +int32_t spine_track_entry_get_reverse(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getReverse() ? -1 : 0; +} + +void spine_track_entry_set_reverse(spine_track_entry entry, int32_t reverse) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setReverse(reverse); +} + +int32_t spine_track_entry_get_shortest_rotation(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getShortestRotation() ? -1 : 0; +} + +void spine_track_entry_set_shortest_rotation(spine_track_entry entry, int32_t shortestRotation) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setShortestRotation(shortestRotation); +} + +float spine_track_entry_get_delay(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getDelay(); +} + +void spine_track_entry_set_delay(spine_track_entry entry, float delay) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setDelay(delay); +} + +float spine_track_entry_get_track_time(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getTrackTime(); +} + +void spine_track_entry_set_track_time(spine_track_entry entry, float trackTime) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setTrackTime(trackTime); +} + +float spine_track_entry_get_track_end(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getTrackEnd(); +} + +void spine_track_entry_set_track_end(spine_track_entry entry, float trackEnd) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setTrackEnd(trackEnd); +} + +float spine_track_entry_get_animation_start(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getAnimationStart(); +} + +void spine_track_entry_set_animation_start(spine_track_entry entry, float animationStart) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setAnimationStart(animationStart); +} + +float spine_track_entry_get_animation_end(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getAnimationEnd(); +} + +void spine_track_entry_set_animation_end(spine_track_entry entry, float animationEnd) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setAnimationEnd(animationEnd); +} + +float spine_track_entry_get_animation_last(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getAnimationLast(); +} + +void spine_track_entry_set_animation_last(spine_track_entry entry, float animationLast) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setAnimationLast(animationLast); +} + +float spine_track_entry_get_animation_time(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getAnimationTime(); +} + +float spine_track_entry_get_time_scale(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getTimeScale(); +} + +void spine_track_entry_set_time_scale(spine_track_entry entry, float timeScale) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setTimeScale(timeScale); +} + +float spine_track_entry_get_alpha(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getAlpha(); +} + +void spine_track_entry_set_alpha(spine_track_entry entry, float alpha) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setAlpha(alpha); +} + +float spine_track_entry_get_event_threshold(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getEventThreshold(); +} + +void spine_track_entry_set_event_threshold(spine_track_entry entry, float eventThreshold) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setEventThreshold(eventThreshold); +} + +float spine_track_entry_get_attachment_threshold(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getAttachmentThreshold(); +} + +void spine_track_entry_set_attachment_threshold(spine_track_entry entry, float attachmentThreshold) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setAttachmentThreshold(attachmentThreshold); +} + +float spine_track_entry_get_draw_order_threshold(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getDrawOrderThreshold(); +} + +void spine_track_entry_set_draw_order_threshold(spine_track_entry entry, float drawOrderThreshold) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setDrawOrderThreshold(drawOrderThreshold); +} + +spine_track_entry spine_track_entry_get_next(spine_track_entry entry) { + if (entry == nullptr) return nullptr; + TrackEntry *_entry = (TrackEntry *) entry; + return (spine_track_entry) _entry->getNext(); +} + +int32_t spine_track_entry_is_complete(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->isComplete() ? -1 : 0; +} + +float spine_track_entry_get_mix_time(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getMixTime(); +} + +void spine_track_entry_set_mix_time(spine_track_entry entry, float mixTime) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setMixTime(mixTime); +} + +float spine_track_entry_get_mix_duration(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getMixDuration(); +} + +void spine_track_entry_set_mix_duration(spine_track_entry entry, float mixDuration) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setMixDuration(mixDuration); +} + +spine_mix_blend spine_track_entry_get_mix_blend(spine_track_entry entry) { + if (entry == nullptr) return SPINE_MIX_BLEND_SETUP; + TrackEntry *_entry = (TrackEntry *) entry; + return (spine_mix_blend) _entry->getMixBlend(); +} + +void spine_track_entry_set_mix_blend(spine_track_entry entry, spine_mix_blend mixBlend) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->setMixBlend((MixBlend) mixBlend); +} + +spine_track_entry spine_track_entry_get_mixing_from(spine_track_entry entry) { + if (entry == nullptr) return nullptr; + TrackEntry *_entry = (TrackEntry *) entry; + return (spine_track_entry) _entry->getMixingFrom(); +} + +spine_track_entry spine_track_entry_get_mixing_to(spine_track_entry entry) { + if (entry == nullptr) return nullptr; + TrackEntry *_entry = (TrackEntry *) entry; + return (spine_track_entry) _entry->getMixingTo(); +} + +void spine_track_entry_reset_rotation_directions(spine_track_entry entry) { + if (entry == nullptr) return; + TrackEntry *_entry = (TrackEntry *) entry; + _entry->resetRotationDirections(); +} + +float spine_track_entry_get_track_complete(spine_track_entry entry) { + if (entry == nullptr) return 0; + TrackEntry *_entry = (TrackEntry *) entry; + return _entry->getTrackComplete(); +} + +// Skeleton + +void spine_skeleton_update_cache(spine_skeleton skeleton) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->updateCache(); +} + +void spine_skeleton_update_world_transform(spine_skeleton skeleton) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->updateWorldTransform(); +} + +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; + Bone *_bone = (Bone *) parent; + _skeleton->updateWorldTransform(_bone); +} + +void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setToSetupPose(); +} + +void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setBonesToSetupPose(); +} + +void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setSlotsToSetupPose(); +} + +spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const utf8 *boneName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_bone) _skeleton->findBone(boneName); +} + +spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const utf8 *slotName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_slot) _skeleton->findSlot(slotName); +} + +void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const utf8 *skinName) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setSkin(skinName); +} + +void spine_skeleton_set_skin(spine_skeleton skeleton, spine_skin skin) { + if (skeleton == nullptr) return; + if (skin == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setSkin((Skin *) skin); +} + +spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const utf8 *slotName, const utf8 *attachmentName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_attachment) _skeleton->getAttachment(slotName, attachmentName); +} + +spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int32_t slotIndex, const utf8 *attachmentName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_attachment) _skeleton->getAttachment(slotIndex, attachmentName); +} + +void spine_skeleton_set_attachment(spine_skeleton skeleton, const utf8 *slotName, const utf8 *attachmentName) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + return _skeleton->setAttachment(slotName, attachmentName); +} + +spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const utf8 *constraintName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_ik_constraint) _skeleton->findIkConstraint(constraintName); +} + +spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const utf8 *constraintName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_transform_constraint) _skeleton->findTransformConstraint(constraintName); +} + +spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const utf8 *constraintName) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_path_constraint) _skeleton->findPathConstraint(constraintName); +} + +spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton) { + _spine_bounds *bounds = (_spine_bounds *) malloc(sizeof(_spine_bounds)); + if (skeleton == nullptr) return (spine_bounds) bounds; + Skeleton *_skeleton = (Skeleton *) skeleton; + Vector vertices; + _skeleton->getBounds(bounds->x, bounds->y, bounds->width, bounds->height, vertices); + return (spine_bounds) bounds; +} + +spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_bone) _skeleton->getRootBone(); +} + +spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_skeleton_data) _skeleton->getData(); +} + +int32_t spine_skeleton_get_num_bones(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (int32_t) _skeleton->getBones().size(); +} + +spine_bone *spine_skeleton_get_bones(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_bone *) _skeleton->getBones().buffer(); +} + +int32_t spine_skeleton_get_num_slots(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (int32_t) _skeleton->getSlots().size(); +} + +spine_slot *spine_skeleton_get_slots(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_slot *) _skeleton->getSlots().buffer(); +} + +int32_t spine_skeleton_get_num_draw_order(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (int32_t) _skeleton->getDrawOrder().size(); +} + +spine_slot *spine_skeleton_get_draw_order(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_slot *) _skeleton->getDrawOrder().buffer(); +} + +int32_t spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (int32_t) _skeleton->getIkConstraints().size(); +} + +spine_ik_constraint *spine_skeleton_get_ik_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_ik_constraint *) _skeleton->getIkConstraints().buffer(); +} + +int32_t spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (int32_t) _skeleton->getTransformConstraints().size(); +} + +spine_transform_constraint *spine_skeleton_get_transform_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_transform_constraint *) _skeleton->getTransformConstraints().buffer(); +} + +int32_t spine_skeleton_get_num_path_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (int32_t) _skeleton->getPathConstraints().size(); +} + +spine_path_constraint *spine_skeleton_get_path_constraints(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_path_constraint *) _skeleton->getPathConstraints().buffer(); +} + +spine_skin spine_skeleton_get_skin(spine_skeleton skeleton) { + if (skeleton == nullptr) return nullptr; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_skin) _skeleton->getSkin(); +} + +spine_color spine_skeleton_get_color(spine_skeleton skeleton) { + if (skeleton == nullptr) return (spine_color) &NULL_COLOR; + Skeleton *_skeleton = (Skeleton *) skeleton; + return (spine_color) &_skeleton->getColor(); +} + +void spine_skeleton_set_color(spine_skeleton skeleton, float r, float g, float b, float a) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->getColor().set(r, g, b, a); +} + +void spine_skeleton_set_position(spine_skeleton skeleton, float x, float y) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setPosition(x, y); +} + +float spine_skeleton_get_x(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return _skeleton->getX(); +} + +void spine_skeleton_set_x(spine_skeleton skeleton, float x) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setX(x); +} + +float spine_skeleton_get_y(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return _skeleton->getY(); +} + +void spine_skeleton_set_y(spine_skeleton skeleton, float y) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setY(y); +} + +float spine_skeleton_get_scale_x(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return _skeleton->getScaleX(); +} + +void spine_skeleton_set_scale_x(spine_skeleton skeleton, float scaleX) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setScaleX(scaleX); +} + +float spine_skeleton_get_scale_y(spine_skeleton skeleton) { + if (skeleton == nullptr) return 0; + Skeleton *_skeleton = (Skeleton *) skeleton; + return _skeleton->getScaleY(); +} + +void spine_skeleton_set_scale_y(spine_skeleton skeleton, float scaleY) { + if (skeleton == nullptr) return; + Skeleton *_skeleton = (Skeleton *) skeleton; + _skeleton->setScaleY(scaleY); +} + +// EventData + +const utf8 *spine_event_data_get_name(spine_event_data event) { + if (event == nullptr) return nullptr; + EventData *_event = (EventData *) event; + return (utf8 *) _event->getName().buffer(); +} + +int32_t spine_event_data_get_int_value(spine_event_data event) { + if (event == nullptr) return 0; + EventData *_event = (EventData *) event; + return _event->getIntValue(); +} + +void spine_event_data_set_int_value(spine_event_data event, int32_t value) { + if (event == nullptr) return; + EventData *_event = (EventData *) event; + _event->setIntValue(value); +} + +float spine_event_data_get_float_value(spine_event_data event) { + if (event == nullptr) return 0; + EventData *_event = (EventData *) event; + return _event->getFloatValue(); +} + +void spine_event_data_set_float_value(spine_event_data event, float value) { + if (event == nullptr) return; + EventData *_event = (EventData *) event; + _event->setFloatValue(value); +} + +const utf8 *spine_event_data_get_string_value(spine_event_data event) { + if (event == nullptr) return nullptr; + EventData *_event = (EventData *) event; + return (utf8 *) _event->getStringValue().buffer(); +} + +void spine_event_data_set_string_value(spine_event_data event, const utf8 *value) { + if (event == nullptr) return; + EventData *_event = (EventData *) event; + _event->setStringValue(value); +} + +const utf8 *spine_event_data_get_audio_path(spine_event_data event) { + if (event == nullptr) return nullptr; + EventData *_event = (EventData *) event; + return (utf8 *) _event->getAudioPath().buffer(); +} + +float spine_event_data_get_volume(spine_event_data event) { + if (event == nullptr) return 0; + EventData *_event = (EventData *) event; + return _event->getVolume(); +} + +void spine_event_data_set_volume(spine_event_data event, float volume) { + if (event == nullptr) return; + EventData *_event = (EventData *) event; + _event->setVolume(volume); +} + +float spine_event_data_get_balance(spine_event_data event) { + if (event == nullptr) return 0; + EventData *_event = (EventData *) event; + return _event->getBalance(); +} + +void spine_event_data_set_balance(spine_event_data event, float balance) { + if (event == nullptr) return; + EventData *_event = (EventData *) event; + _event->setBalance(balance); +} + +// Event + +spine_event_data spine_event_get_data(spine_event event) { + if (event == nullptr) return nullptr; + Event *_event = (Event *) event; + return (spine_event_data) &_event->getData(); +} + +float spine_event_get_time(spine_event event) { + if (event == nullptr) return 0; + Event *_event = (Event *) event; + return _event->getTime(); +} + +int32_t spine_event_get_int_value(spine_event event) { + if (event == nullptr) return 0; + Event *_event = (Event *) event; + return _event->getIntValue(); +} + +void spine_event_set_int_value(spine_event event, int32_t value) { + if (event == nullptr) return; + Event *_event = (Event *) event; + _event->setIntValue(value); +} + +float spine_event_get_float_value(spine_event event) { + if (event == nullptr) return 0; + Event *_event = (Event *) event; + return _event->getFloatValue(); +} + +void spine_event_set_float_value(spine_event event, float value) { + if (event == nullptr) return; + Event *_event = (Event *) event; + _event->setFloatValue(value); +} + +const utf8 *spine_event_get_string_value(spine_event event) { + if (event == nullptr) return nullptr; + Event *_event = (Event *) event; + return (utf8 *) _event->getStringValue().buffer(); +} + +void spine_event_set_string_value(spine_event event, const utf8 *value) { + if (event == nullptr) return; + Event *_event = (Event *) event; + _event->setStringValue(value); +} + +float spine_event_get_volume(spine_event event) { + if (event == nullptr) return 0; + Event *_event = (Event *) event; + return _event->getVolume(); +} + +void spine_event_set_volume(spine_event event, float volume) { + if (event == nullptr) return; + Event *_event = (Event *) event; + _event->setVolume(volume); +} + +float spine_event_get_balance(spine_event event) { + if (event == nullptr) return 0; + Event *_event = (Event *) event; + return _event->getBalance(); +} + +void spine_event_set_balance(spine_event event, float balance) { + if (event == nullptr) return; + Event *_event = (Event *) event; + _event->setBalance(balance); +} + +// SlotData +int32_t spine_slot_data_get_index(spine_slot_data slot) { + if (slot == nullptr) return 0; + SlotData *_slot = (SlotData *) slot; + return _slot->getIndex(); +} + +const utf8 *spine_slot_data_get_name(spine_slot_data slot) { + if (slot == nullptr) return nullptr; + SlotData *_slot = (SlotData *) slot; + return (utf8 *) _slot->getName().buffer(); +} + +spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot) { + if (slot == nullptr) return nullptr; + SlotData *_slot = (SlotData *) slot; + return (spine_bone_data) &_slot->getBoneData(); +} + +spine_color spine_slot_data_get_color(spine_slot_data slot) { + if (slot == nullptr) return (spine_color) &NULL_COLOR; + SlotData *_slot = (SlotData *) slot; + return (spine_color) &_slot->getColor(); +} + +void spine_slot_data_set_color(spine_slot_data slot, float r, float g, float b, float a) { + if (slot == nullptr) return; + SlotData *_slot = (SlotData *) slot; + _slot->getColor().set(r, g, b, a); +} + +spine_color spine_slot_data_get_dark_color(spine_slot_data slot) { + if (slot == nullptr) return (spine_color) &NULL_COLOR; + SlotData *_slot = (SlotData *) slot; + return (spine_color) &_slot->getDarkColor(); +} + +void spine_slot_data_set_dark_color(spine_slot_data slot, float r, float g, float b, float a) { + if (slot == nullptr) return; + SlotData *_slot = (SlotData *) slot; + _slot->getDarkColor().set(r, g, b, a); +} + +int32_t spine_slot_data_has_dark_color(spine_slot_data slot) { + if (slot == nullptr) return 0; + SlotData *_slot = (SlotData *) slot; + return _slot->hasDarkColor() ? -1 : 0; +} + +void spine_slot_data_set_has_dark_color(spine_slot_data slot, int32_t hasDarkColor) { + if (slot == nullptr) return; + SlotData *_slot = (SlotData *) slot; + _slot->setHasDarkColor(hasDarkColor); +} + +const utf8 *spine_slot_data_get_attachment_name(spine_slot_data slot) { + if (slot == nullptr) return nullptr; + SlotData *_slot = (SlotData *) slot; + return (utf8 *) _slot->getAttachmentName().buffer(); +} + +void spine_slot_data_set_attachment_name(spine_slot_data slot, const utf8 *attachmentName) { + if (slot == nullptr) return; + SlotData *_slot = (SlotData *) slot; + _slot->setAttachmentName(attachmentName); +} + +spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot) { + if (slot == nullptr) return SPINE_BLEND_MODE_NORMAL; + SlotData *_slot = (SlotData *) slot; + return (spine_blend_mode) _slot->getBlendMode(); +} + +// Slot +void spine_slot_set_to_setup_pose(spine_slot slot) { + if (slot == nullptr) return; + Slot *_slot = (Slot *) slot; + _slot->setToSetupPose(); +} + +spine_slot_data spine_slot_get_data(spine_slot slot) { + if (slot == nullptr) return nullptr; + Slot *_slot = (Slot *) slot; + return (spine_slot_data) &_slot->getData(); +} + +spine_bone spine_slot_get_bone(spine_slot slot) { + if (slot == nullptr) return nullptr; + Slot *_slot = (Slot *) slot; + return (spine_bone) &_slot->getBone(); +} + +spine_skeleton spine_slot_get_skeleton(spine_slot slot) { + if (slot == nullptr) return nullptr; + Slot *_slot = (Slot *) slot; + return (spine_skeleton) &_slot->getSkeleton(); +} + +spine_color spine_slot_get_color(spine_slot slot) { + if (slot == nullptr) return (spine_color) &NULL_COLOR; + Slot *_slot = (Slot *) slot; + return (spine_color) &_slot->getColor(); +} + +void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a) { + if (slot == nullptr) return; + Slot *_slot = (Slot *) slot; + _slot->getColor().set(r, g, b, a); +} + +spine_color spine_slot_get_dark_color(spine_slot slot) { + if (slot == nullptr) return (spine_color) &NULL_COLOR; + Slot *_slot = (Slot *) slot; + return (spine_color) &_slot->getDarkColor(); +} + +void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a) { + if (slot == nullptr) return; + Slot *_slot = (Slot *) slot; + _slot->getDarkColor().set(r, g, b, a); +} + +int32_t spine_slot_has_dark_color(spine_slot slot) { + if (slot == nullptr) return 0; + Slot *_slot = (Slot *) slot; + return _slot->hasDarkColor() ? -1 : 0; +} + +spine_attachment spine_slot_get_attachment(spine_slot slot) { + if (slot == nullptr) return nullptr; + Slot *_slot = (Slot *) slot; + return (spine_attachment) _slot->getAttachment(); +} + +void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment) { + if (slot == nullptr) return; + Slot *_slot = (Slot *) slot; + _slot->setAttachment((Attachment *) attachment); +} + +int32_t spine_slot_get_sequence_index(spine_slot slot) { + if (slot == nullptr) return 0; + Slot *_slot = (Slot *) slot; + return _slot->getSequenceIndex(); +} + +void spine_slot_set_sequence_index(spine_slot slot, int32_t sequenceIndex) { + if (slot == nullptr) return; + Slot *_slot = (Slot *) slot; + _slot->setSequenceIndex(sequenceIndex); +} + +// BoneData +int32_t spine_bone_data_get_index(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getIndex(); +} + +const utf8 *spine_bone_data_get_name(spine_bone_data data) { + if (data == nullptr) return nullptr; + BoneData *_data = (BoneData *) data; + return (utf8 *) _data->getName().buffer(); +} + +spine_bone_data spine_bone_data_get_parent(spine_bone_data data) { + if (data == nullptr) return nullptr; + BoneData *_data = (BoneData *) data; + return (spine_bone_data) _data->getParent(); +} + +float spine_bone_data_get_length(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getLength(); +} + +void spine_bone_data_set_length(spine_bone_data data, float length) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setLength(length); +} + +float spine_bone_data_get_x(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getX(); +} + +void spine_bone_data_set_x(spine_bone_data data, float x) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setX(x); +} + +float spine_bone_data_get_y(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getY(); +} + +void spine_bone_data_set_y(spine_bone_data data, float y) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setY(y); +} + +float spine_bone_data_get_rotation(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getRotation(); +} + +void spine_bone_data_set_rotation(spine_bone_data data, float rotation) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setRotation(rotation); +} + +float spine_bone_data_get_scale_x(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getScaleX(); +} + +void spine_bone_data_set_scale_x(spine_bone_data data, float scaleX) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setScaleX(scaleX); +} + +float spine_bone_data_get_scale_y(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getScaleY(); +} + +void spine_bone_data_set_scale_y(spine_bone_data data, float scaleY) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setScaleY(scaleY); +} + +float spine_bone_data_get_shear_x(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getShearX(); +} + +void spine_bone_data_set_shear_x(spine_bone_data data, float shearX) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setShearX(shearX); +} + +float spine_bone_data_get_shear_y(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->getShearY(); +} + +void spine_bone_data_set_shear_y(spine_bone_data data, float y) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setShearY(y); +} + +spine_transform_mode spine_bone_data_get_transform_mode(spine_bone_data data) { + if (data == nullptr) return SPINE_TRANSFORM_MODE_NORMAL; + BoneData *_data = (BoneData *) data; + return (spine_transform_mode) _data->getTransformMode(); +} + +void spine_bone_data_set_transform_mode(spine_bone_data data, spine_transform_mode mode) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setTransformMode((TransformMode) mode); +} + +int32_t spine_bone_data_is_skin_required(spine_bone_data data) { + if (data == nullptr) return 0; + BoneData *_data = (BoneData *) data; + return _data->isSkinRequired() ? -1 : 0; +} + +void spine_bone_data_set_is_skin_required(spine_bone_data data, int32_t isSkinRequired) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->setSkinRequired(isSkinRequired); +} + +spine_color spine_bone_data_get_color(spine_bone_data data) { + if (data == nullptr) return (spine_color) &NULL_COLOR; + BoneData *_data = (BoneData *) data; + return (spine_color) &_data->getColor(); +} + +void spine_bone_data_set_color(spine_bone_data data, float r, float g, float b, float a) { + if (data == nullptr) return; + BoneData *_data = (BoneData *) data; + _data->getColor().set(r, g, b, a); +} + +// Bone +void spine_bone_set_is_y_down(int32_t yDown) { + Bone::setYDown(yDown); +} + +int32_t spine_bone_get_is_y_down() { + return Bone::isYDown() ? -1 : 0; +} + +void spine_bone_update(spine_bone bone) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->update(); +} + +void spine_bone_update_world_transform(spine_bone bone) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->updateWorldTransform(); +} + +void spine_bone_update_world_transform_with(spine_bone bone, float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->updateWorldTransform(x, y, rotation, scaleX, scaleY, shearX, shearY); +} + +void spine_bone_update_applied_transform(spine_bone bone) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->updateAppliedTransform(); +} + +void spine_bone_set_to_setup_pose(spine_bone bone) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setToSetupPose(); +} + +spine_vector spine_bone_world_to_local(spine_bone bone, float worldX, float worldY) { + _spine_vector *coords = SpineExtension::calloc<_spine_vector>(1, __FILE__, __LINE__); + if (bone == nullptr) return (spine_vector) coords; + Bone *_bone = (Bone *) bone; + _bone->worldToLocal(worldX, worldY, coords->x, coords->y); + return (spine_vector) coords; +} + +spine_vector spine_bone_local_to_world(spine_bone bone, float localX, float localY) { + _spine_vector *coords = SpineExtension::calloc<_spine_vector>(1, __FILE__, __LINE__); + if (bone == nullptr) return (spine_vector) coords; + Bone *_bone = (Bone *) bone; + _bone->localToWorld(localX, localY, coords->x, coords->y); + return (spine_vector) coords; +} + +float spine_bone_world_to_local_rotation(spine_bone bone, float worldRotation) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->worldToLocalRotation(worldRotation); +} + +float spine_bone_local_to_world_rotation(spine_bone bone, float localRotation) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->localToWorldRotation(localRotation); +} + +void spine_bone_rotate_world(spine_bone bone, float degrees) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->rotateWorld(degrees); +} + +float spine_bone_get_world_to_local_rotation_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldToLocalRotationX(); +} + +float spine_bone_get_world_to_local_rotation_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldToLocalRotationY(); +} + +spine_bone_data spine_bone_get_data(spine_bone bone) { + if (bone == nullptr) return nullptr; + Bone *_bone = (Bone *) bone; + return (spine_bone_data) &_bone->getData(); +} + +spine_skeleton spine_bone_get_skeleton(spine_bone bone) { + if (bone == nullptr) return nullptr; + Bone *_bone = (Bone *) bone; + return (spine_skeleton) &_bone->getSkeleton(); +} + +spine_bone spine_bone_get_parent(spine_bone bone) { + if (bone == nullptr) return nullptr; + Bone *_bone = (Bone *) bone; + return (spine_bone) _bone->getParent(); +} + +int32_t spine_bone_get_num_children(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return (int32_t) _bone->getChildren().size(); +} + +spine_bone *spine_bone_get_children(spine_bone bone) { + if (bone == nullptr) return nullptr; + Bone *_bone = (Bone *) bone; + return (spine_bone *) _bone->getChildren().buffer(); +} + +float spine_bone_get_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getX(); +} + +void spine_bone_set_x(spine_bone bone, float x) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setX(x); +} + +float spine_bone_get_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getY(); +} + +void spine_bone_set_y(spine_bone bone, float y) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setY(y); +} + +float spine_bone_get_rotation(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getRotation(); +} + +void spine_bone_set_rotation(spine_bone bone, float rotation) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setRotation(rotation); +} + +float spine_bone_get_scale_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getScaleX(); +} + +void spine_bone_set_scale_x(spine_bone bone, float scaleX) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setScaleX(scaleX); +} + +float spine_bone_get_scale_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getScaleY(); +} + +void spine_bone_set_scale_y(spine_bone bone, float scaleY) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setScaleY(scaleY); +} + +float spine_bone_get_shear_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getShearX(); +} + +void spine_bone_set_shear_x(spine_bone bone, float shearX) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setShearX(shearX); +} + +float spine_bone_get_shear_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getShearY(); +} + +void spine_bone_set_shear_y(spine_bone bone, float shearY) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setShearY(shearY); +} + +float spine_bone_get_applied_rotation(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAppliedRotation(); +} + +void spine_bone_set_applied_rotation(spine_bone bone, float rotation) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAppliedRotation(rotation); +} + +float spine_bone_get_a_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAX(); +} + +void spine_bone_set_a_x(spine_bone bone, float x) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAX(x); +} + +float spine_bone_get_a_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAY(); +} + +void spine_bone_set_a_y(spine_bone bone, float y) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAY(y); +} + +float spine_bone_get_a_scale_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAScaleX(); +} + +void spine_bone_set_a_scale_x(spine_bone bone, float scaleX) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAScaleX(scaleX); +} + +float spine_bone_get_a_scale_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAScaleY(); +} + +void spine_bone_set_a_scale_y(spine_bone bone, float scaleY) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAScaleY(scaleY); +} + +float spine_bone_get_a_shear_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAShearX(); +} + +void spine_bone_set_a_shear_x(spine_bone bone, float shearX) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAShearX(shearX); +} + +float spine_bone_get_a_shear_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getAShearY(); +} + +void spine_bone_set_shear_a_y(spine_bone bone, float shearY) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setAShearY(shearY); +} + +float spine_bone_get_a(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getA(); +} + +void spine_bone_set_a(spine_bone bone, float a) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setA(a); +} + +float spine_bone_get_b(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getB(); +} + +void spine_bone_set_b(spine_bone bone, float b) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setB(b); +} + +float spine_bone_get_c(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getC(); +} + +void spine_bone_set_c(spine_bone bone, float c) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setC(c); +} + +float spine_bone_get_d(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getD(); +} + +void spine_bone_set_d(spine_bone bone, float d) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setD(d); +} + +float spine_bone_get_world_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldX(); +} + +void spine_bone_set_world_x(spine_bone bone, float worldX) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setWorldX(worldX); +} + +float spine_bone_get_world_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldY(); +} + +void spine_bone_set_world_y(spine_bone bone, float worldY) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setWorldY(worldY); +} + +float spine_bone_get_world_rotation_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldRotationX(); +} + +float spine_bone_get_world_rotation_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldToLocalRotationY(); +} + +float spine_bone_get_world_scale_x(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldScaleX(); +} + +float spine_bone_get_world_scale_y(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->getWorldScaleY(); +} + +int32_t spine_bone_get_is_active(spine_bone bone) { + if (bone == nullptr) return 0; + Bone *_bone = (Bone *) bone; + return _bone->isActive() ? -1 : 0; +} + +void spine_bone_set_is_active(spine_bone bone, int32_t isActive) { + if (bone == nullptr) return; + Bone *_bone = (Bone *) bone; + _bone->setActive(isActive); +} + +// Attachment +const utf8 *spine_attachment_get_name(spine_attachment attachment) { + if (attachment == nullptr) return nullptr; + Attachment *_attachment = (Attachment *) attachment; + return (utf8 *) _attachment->getName().buffer(); +} + +spine_attachment_type spine_attachment_get_type(spine_attachment attachment) { + if (attachment == nullptr) return SPINE_ATTACHMENT_REGION; + Attachment *_attachment = (Attachment *) attachment; + if (_attachment->getRTTI().isExactly(RegionAttachment::rtti)) { + return SPINE_ATTACHMENT_REGION; + } else if (_attachment->getRTTI().isExactly(MeshAttachment::rtti)) { + return SPINE_ATTACHMENT_MESH; + } else if (_attachment->getRTTI().isExactly(ClippingAttachment::rtti)) { + return SPINE_ATTACHMENT_CLIPPING; + } else if (_attachment->getRTTI().isExactly(BoundingBoxAttachment::rtti)) { + return SPINE_ATTACHMENT_BOUNDING_BOX; + } else if (_attachment->getRTTI().isExactly(PathAttachment::rtti)) { + return SPINE_ATTACHMENT_PATH; + } else if (_attachment->getRTTI().isExactly(PointAttachment::rtti)) { + return SPINE_ATTACHMENT_POINT; + } else { + return SPINE_ATTACHMENT_REGION; + } +} + +spine_attachment spine_attachment_copy(spine_attachment attachment) { + if (attachment == nullptr) return nullptr; + Attachment *_attachment = (Attachment *) attachment; + return (spine_attachment) _attachment->copy(); +} + +void spine_attachment_dispose(spine_attachment attachment) { + if (attachment == nullptr) return; + Attachment *_attachment = (Attachment *) attachment; + delete _attachment; +} + +// PointAttachment +spine_vector spine_point_attachment_compute_world_position(spine_point_attachment attachment, spine_bone bone) { + _spine_vector *result = SpineExtension::calloc<_spine_vector>(1, __FILE__, __LINE__); + if (attachment == nullptr) return (spine_vector) result; + PointAttachment *_attachment = (PointAttachment *) attachment; + _attachment->computeWorldPosition(*(Bone *) bone, result->x, result->y); + return (spine_vector) result; +} + +float spine_point_attachment_compute_world_rotation(spine_point_attachment attachment, spine_bone bone) { + if (attachment == nullptr) return 0; + PointAttachment *_attachment = (PointAttachment *) attachment; + return _attachment->computeWorldRotation(*(Bone *) bone); +} + +float spine_point_attachment_get_x(spine_point_attachment attachment) { + if (attachment == nullptr) return 0; + PointAttachment *_attachment = (PointAttachment *) attachment; + return _attachment->getX(); +} + +void spine_point_attachment_set_x(spine_point_attachment attachment, float x) { + if (attachment == nullptr) return; + PointAttachment *_attachment = (PointAttachment *) attachment; + _attachment->setX(x); +} + +float spine_point_attachment_get_y(spine_point_attachment attachment) { + if (attachment == nullptr) return 0; + PointAttachment *_attachment = (PointAttachment *) attachment; + return _attachment->getY(); +} + +void spine_point_attachment_set_y(spine_point_attachment attachment, float y) { + if (attachment == nullptr) return; + PointAttachment *_attachment = (PointAttachment *) attachment; + _attachment->setY(y); +} + +float spine_point_attachment_get_rotation(spine_point_attachment attachment) { + if (attachment == nullptr) return 0; + PointAttachment *_attachment = (PointAttachment *) attachment; + return _attachment->getRotation(); +} + +void spine_point_attachment_set_rotation(spine_point_attachment attachment, float rotation) { + if (attachment == nullptr) return; + PointAttachment *_attachment = (PointAttachment *) attachment; + _attachment->setRotation(rotation); +} + +spine_color spine_point_attachment_get_color(spine_point_attachment attachment) { + if (attachment == nullptr) return (spine_color) &NULL_COLOR; + PointAttachment *_attachment = (PointAttachment *) attachment; + return (spine_color) &_attachment->getColor(); +} + +void spine_point_attachment_set_color(spine_point_attachment attachment, float r, float g, float b, float a) { + if (attachment == nullptr) return; + PointAttachment *_attachment = (PointAttachment *) attachment; + _attachment->getColor().set(r, g, b, a); +} + +// RegionAttachment +void spine_region_attachment_update_region(spine_region_attachment attachment) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->updateRegion(); +} + +void spine_region_attachment_compute_world_vertices(spine_region_attachment attachment, spine_slot slot, float *worldVertices) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->computeWorldVertices(*(Slot *) slot, worldVertices, 0); +} + +float spine_region_attachment_get_x(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getX(); +} + +void spine_region_attachment_set_x(spine_region_attachment attachment, float x) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setX(x); +} + +float spine_region_attachment_get_y(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getY(); +} + +void spine_region_attachment_set_y(spine_region_attachment attachment, float y) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setY(y); +} + +float spine_region_attachment_get_rotation(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getRotation(); +} + +void spine_region_attachment_set_rotation(spine_region_attachment attachment, float rotation) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setRotation(rotation); +} + +float spine_region_attachment_get_scale_x(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getScaleX(); +} + +void spine_region_attachment_set_scale_x(spine_region_attachment attachment, float scaleX) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setScaleX(scaleX); +} + +float spine_region_attachment_get_scale_y(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getScaleY(); +} + +void spine_region_attachment_set_scale_y(spine_region_attachment attachment, float scaleY) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setScaleY(scaleY); +} + +float spine_region_attachment_get_width(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getWidth(); +} + +void spine_region_attachment_set_width(spine_region_attachment attachment, float width) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setWidth(width); +} + +float spine_region_attachment_get_height(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getHeight(); +} + +void spine_region_attachment_set_height(spine_region_attachment attachment, float height) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->setHeight(height); +} + +spine_color spine_region_attachment_get_color(spine_region_attachment attachment) { + if (attachment == nullptr) return (spine_color) &NULL_COLOR; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return (spine_color) &_attachment->getColor(); +} + +void spine_region_attachment_set_color(spine_region_attachment attachment, float r, float g, float b, float a) { + if (attachment == nullptr) return; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + _attachment->getColor().set(r, g, b, a); +} + +const utf8 *spine_region_attachment_get_path(spine_region_attachment attachment) { + if (attachment == nullptr) return nullptr; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return (utf8 *) _attachment->getPath().buffer(); +} + +spine_texture_region spine_region_attachment_get_region(spine_region_attachment attachment) { + if (attachment == nullptr) return nullptr; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return (spine_texture_region) _attachment->getRegion(); +} + +spine_sequence spine_region_attachment_get_sequence(spine_region_attachment attachment) { + if (attachment == nullptr) return nullptr; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return (spine_sequence) _attachment->getSequence(); +} + +int32_t spine_region_attachment_get_num_offset(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return (int32_t) _attachment->getOffset().size(); +} + +float *spine_region_attachment_get_offset(spine_region_attachment attachment) { + if (attachment == nullptr) return nullptr; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getOffset().buffer(); +} + +int32_t spine_region_attachment_get_num_uvs(spine_region_attachment attachment) { + if (attachment == nullptr) return 0; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return (int32_t) _attachment->getUVs().size(); +} + +float *spine_region_attachment_get_uvs(spine_region_attachment attachment) { + if (attachment == nullptr) return nullptr; + RegionAttachment *_attachment = (RegionAttachment *) attachment; + return _attachment->getUVs().buffer(); +} + +// VertexAttachment +int32_t spine_vertex_attachment_get_world_vertices_length(spine_vertex_attachment attachment) { + if (attachment == nullptr) return 0; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + return (int32_t) _attachment->getWorldVerticesLength(); +} + +void spine_vertex_attachment_compute_world_vertices(spine_vertex_attachment attachment, spine_slot slot, float *worldVertices) { + if (attachment == nullptr) return; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + _attachment->computeWorldVertices(*(Slot *) slot, worldVertices); +} + +int32_t spine_vertex_attachment_get_num_bones(spine_vertex_attachment attachment) { + if (attachment == nullptr) return 0; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + return (int32_t) _attachment->getBones().size(); +} + +int32_t *spine_vertex_attachment_get_bones(spine_vertex_attachment attachment) { + if (attachment == nullptr) return nullptr; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + return _attachment->getBones().buffer(); +} + +// VertexAttachment +int32_t spine_vertex_attachment_get_num_vertices(spine_vertex_attachment attachment) { + if (attachment == nullptr) return 0; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + return (int32_t) _attachment->getVertices().size(); +} + +float *spine_vertex_attachment_get_vertices(spine_vertex_attachment attachment) { + if (attachment == nullptr) return nullptr; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + return _attachment->getVertices().buffer(); +} + +spine_attachment spine_vertex_attachment_get_timeline_attachment(spine_vertex_attachment attachment) { + if (attachment == nullptr) return nullptr; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + return (spine_attachment) _attachment->getTimelineAttachment(); +} + +void spine_vertex_attachment_set_timeline_attachment(spine_vertex_attachment attachment, spine_attachment timelineAttachment) { + if (attachment == nullptr) return; + VertexAttachment *_attachment = (VertexAttachment *) attachment; + _attachment->setTimelineAttachment((Attachment *) timelineAttachment); +} + +// MeshAttachment +void spine_mesh_attachment_update_region(spine_mesh_attachment attachment) { + if (attachment == nullptr) return; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + _attachment->updateRegion(); +} + +int32_t spine_mesh_attachment_get_hull_length(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getHullLength(); +} + +void spine_mesh_attachment_set_hull_length(spine_mesh_attachment attachment, int32_t hullLength) { + if (attachment == nullptr) return; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + _attachment->setHullLength(hullLength); +} + +int32_t spine_mesh_attachment_get_num_region_uvs(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (int32_t) _attachment->getRegionUVs().size(); +} + +float *spine_mesh_attachment_get_region_uvs(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getRegionUVs().buffer(); +} + +int32_t spine_mesh_attachment_get_num_uvs(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (int32_t) _attachment->getUVs().size(); +} + +float *spine_mesh_attachment_get_uvs(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getUVs().buffer(); +} + +int32_t spine_mesh_attachment_get_num_triangles(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (int32_t) _attachment->getTriangles().size(); +} + +uint16_t *spine_mesh_attachment_get_triangles(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getTriangles().buffer(); +} + +spine_color spine_mesh_attachment_get_color(spine_mesh_attachment attachment) { + if (attachment == nullptr) return (spine_color) &NULL_COLOR; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (spine_color) &_attachment->getColor(); +} + +void spine_mesh_attachment_set_color(spine_mesh_attachment attachment, float r, float g, float b, float a) { + if (attachment == nullptr) return; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + _attachment->getColor().set(r, g, b, a); +} + +const utf8 *spine_mesh_attachment_get_path(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (utf8 *) _attachment->getPath().buffer(); +} + +spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (spine_texture_region) _attachment->getRegion(); +} + +spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (spine_sequence) _attachment->getSequence(); +} + +spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (spine_mesh_attachment) _attachment->getParentMesh(); +} + +void spine_mesh_attachment_set_parent_mesh(spine_mesh_attachment attachment, spine_mesh_attachment parentMesh) { + if (attachment == nullptr) return; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + _attachment->setParentMesh((MeshAttachment *) parentMesh); +} + +int32_t spine_mesh_attachment_get_num_edges(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return (int32_t) _attachment->getEdges().size(); +} + +unsigned short *spine_mesh_attachment_get_edges(spine_mesh_attachment attachment) { + if (attachment == nullptr) return nullptr; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getEdges().buffer(); +} + +float spine_mesh_attachment_get_width(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getWidth(); +} + +void spine_mesh_attachment_set_width(spine_mesh_attachment attachment, float width) { + if (attachment == nullptr) return; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + _attachment->setWidth(width); +} + +float spine_mesh_attachment_get_height(spine_mesh_attachment attachment) { + if (attachment == nullptr) return 0; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + return _attachment->getHeight(); +} + +void spine_mesh_attachment_set_height(spine_mesh_attachment attachment, float height) { + if (attachment == nullptr) return; + MeshAttachment *_attachment = (MeshAttachment *) attachment; + _attachment->setHeight(height); +} + +// ClippingAttachment +spine_slot_data spine_clipping_attachment_get_end_slot(spine_clipping_attachment attachment) { + if (attachment == nullptr) return nullptr; + ClippingAttachment *_attachment = (ClippingAttachment *) attachment; + return (spine_slot_data) _attachment->getEndSlot(); +} + +void spine_clipping_attachment_set_end_slot(spine_clipping_attachment attachment, spine_slot_data endSlot) { + if (attachment == nullptr) return; + ClippingAttachment *_attachment = (ClippingAttachment *) attachment; + _attachment->setEndSlot((SlotData *) endSlot); +} + +spine_color spine_clipping_attachment_get_color(spine_clipping_attachment attachment) { + if (attachment == nullptr) return (spine_color) &NULL_COLOR; + ClippingAttachment *_attachment = (ClippingAttachment *) attachment; + return (spine_color) &_attachment->getColor(); +} + +void spine_clipping_attachment_set_color(spine_clipping_attachment attachment, float r, float g, float b, float a) { + if (attachment == nullptr) return; + ClippingAttachment *_attachment = (ClippingAttachment *) attachment; + _attachment->getColor().set(r, g, b, a); +} + +// BoundingBoxAttachment +spine_color spine_bounding_box_attachment_get_color(spine_bounding_box_attachment attachment) { + if (attachment == nullptr) return (spine_color) &NULL_COLOR; + BoundingBoxAttachment *_attachment = (BoundingBoxAttachment *) attachment; + return (spine_color) &_attachment->getColor(); +} + +void spine_bounding_box_attachment_set_color(spine_bounding_box_attachment attachment, float r, float g, float b, float a) { + if (attachment == nullptr) return; + BoundingBoxAttachment *_attachment = (BoundingBoxAttachment *) attachment; + _attachment->getColor().set(r, g, b, a); +} + +// PathAttachment +int32_t spine_path_attachment_get_num_lengths(spine_path_attachment attachment) { + if (attachment == nullptr) return 0; + PathAttachment *_attachment = (PathAttachment *) attachment; + return (int32_t) _attachment->getLengths().size(); +} + +float *spine_path_attachment_get_lengths(spine_path_attachment attachment) { + if (attachment == nullptr) return nullptr; + PathAttachment *_attachment = (PathAttachment *) attachment; + return _attachment->getLengths().buffer(); +} + +int32_t spine_path_attachment_get_is_closed(spine_path_attachment attachment) { + if (attachment == nullptr) return 0; + PathAttachment *_attachment = (PathAttachment *) attachment; + return _attachment->isClosed() ? -1 : 0; +} + +void spine_path_attachment_set_is_closed(spine_path_attachment attachment, int32_t isClosed) { + if (attachment == nullptr) return; + PathAttachment *_attachment = (PathAttachment *) attachment; + _attachment->setClosed(isClosed); +} + +int32_t spine_path_attachment_get_is_constant_speed(spine_path_attachment attachment) { + if (attachment == nullptr) return 0; + PathAttachment *_attachment = (PathAttachment *) attachment; + return _attachment->isConstantSpeed() ? -1 : 0; +} + +void spine_path_attachment_set_is_constant_speed(spine_path_attachment attachment, int32_t isConstantSpeed) { + if (attachment == nullptr) return; + PathAttachment *_attachment = (PathAttachment *) attachment; + _attachment->setConstantSpeed(isConstantSpeed); +} + +spine_color spine_path_attachment_get_color(spine_path_attachment attachment) { + if (attachment == nullptr) return (spine_color) &NULL_COLOR; + PathAttachment *_attachment = (PathAttachment *) attachment; + return (spine_color) &_attachment->getColor(); +} + +void spine_path_attachment_set_color(spine_path_attachment attachment, float r, float g, float b, float a) { + if (attachment == nullptr) return; + PathAttachment *_attachment = (PathAttachment *) attachment; + _attachment->getColor().set(r, g, b, a); +} + +// Skin +void spine_skin_set_attachment(spine_skin skin, int32_t slotIndex, const utf8 *name, spine_attachment attachment) { + if (skin == nullptr) return; + Skin *_skin = (Skin *) skin; + _skin->setAttachment(slotIndex, name, (Attachment *) attachment); +} + +spine_attachment spine_skin_get_attachment(spine_skin skin, int32_t slotIndex, const utf8 *name) { + if (skin == nullptr) return nullptr; + Skin *_skin = (Skin *) skin; + return (spine_attachment) _skin->getAttachment(slotIndex, name); +} + +void spine_skin_remove_attachment(spine_skin skin, int32_t slotIndex, const utf8 *name) { + if (skin == nullptr) return; + Skin *_skin = (Skin *) skin; + _skin->removeAttachment(slotIndex, name); +} + +const utf8 *spine_skin_get_name(spine_skin skin) { + if (skin == nullptr) return nullptr; + Skin *_skin = (Skin *) skin; + return (utf8 *) _skin->getName().buffer(); +} + +void spine_skin_add_skin(spine_skin skin, spine_skin other) { + if (skin == nullptr) return; + if (other == nullptr) return; + Skin *_skin = (Skin *) skin; + _skin->addSkin((Skin *) other); +} + +void spine_skin_copy_skin(spine_skin skin, spine_skin other) { + if (skin == nullptr) return; + if (other == nullptr) return; + Skin *_skin = (Skin *) skin; + _skin->copySkin((Skin *) other); +} + +spine_skin_entries spine_skin_get_entries(spine_skin skin) { + if (skin == nullptr) return nullptr; + Skin *_skin = (Skin *) skin; + _spine_skin_entries *entries = SpineExtension::getInstance()->calloc<_spine_skin_entries>(1, __FILE__, __LINE__); + { + Skin::AttachmentMap::Entries mapEntries = _skin->getAttachments(); + while (mapEntries.hasNext()) entries->numEntries++; + } + { + entries->entries = SpineExtension::getInstance()->calloc<_spine_skin_entry>(entries->numEntries, __FILE__, __LINE__); + Skin::AttachmentMap::Entries mapEntries = _skin->getAttachments(); + int32_t i = 0; + while (mapEntries.hasNext()) { + Skin::AttachmentMap::Entry entry = mapEntries.next(); + entries->entries[i++] = {(int32_t) entry._slotIndex, (utf8 *) entry._name.buffer(), (spine_attachment) entry._attachment}; + } + } + return (spine_skin_entries) entries; +} + +int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries) { + if (!entries) return 0; + return ((_spine_skin_entries *) entries)->numEntries; +} + +spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index) { + if (!entries) return 0; + return (spine_skin_entry) & ((_spine_skin_entries *) entries)->entries[index]; +} + +void spine_skin_entries_dispose(spine_skin_entries entries) { + if (entries == nullptr) return; + SpineExtension::getInstance()->free(((_spine_skin_entries *) entries)->entries, __FILE__, __LINE__); + SpineExtension::getInstance()->free(entries, __FILE__, __LINE__); +} + +int32_t spine_skin_entry_get_slot_index(spine_skin_entry entry) { + if (!entry) return 0; + return ((_spine_skin_entry *) entry)->slotIndex; +} + +utf8 *spine_skin_entry_get_name(spine_skin_entry entry) { + if (!entry) return nullptr; + return ((_spine_skin_entry *) entry)->name; +} + +spine_attachment spine_skin_entry_get_attachment(spine_skin_entry entry) { + if (!entry) return nullptr; + return ((_spine_skin_entry *) entry)->attachment; +} + +int32_t spine_skin_get_num_bones(spine_skin skin) { + if (skin == nullptr) return 0; + Skin *_skin = (Skin *) skin; + return (int32_t) _skin->getBones().size(); +} + +spine_bone_data *spine_skin_get_bones(spine_skin skin) { + if (skin == nullptr) return nullptr; + Skin *_skin = (Skin *) skin; + return (spine_bone_data *) _skin->getBones().buffer(); +} + +int32_t spine_skin_get_num_constraints(spine_skin skin) { + if (skin == nullptr) return 0; + Skin *_skin = (Skin *) skin; + return (int32_t) _skin->getConstraints().size(); +} + +spine_constraint_data *spine_skin_get_constraints(spine_skin skin) { + if (skin == nullptr) return nullptr; + Skin *_skin = (Skin *) skin; + return (spine_constraint_data *) _skin->getConstraints().buffer(); +} + +spine_skin spine_skin_create(const utf8 *name) { + if (name == nullptr) return nullptr; + return (spine_skin) new (__FILE__, __LINE__) Skin(name); +} + +void spine_skin_dispose(spine_skin skin) { + if (skin == nullptr) return; + Skin *_skin = (Skin *) skin; + delete _skin; +} + +// ConstraintData +spine_constraint_type spine_constraint_data_get_type(spine_constraint_data data) { + if (data == nullptr) return SPINE_CONSTRAINT_IK; + ConstraintData *_data = (ConstraintData *) data; + if (_data->getRTTI().isExactly(IkConstraintData::rtti)) { + return SPINE_CONSTRAINT_IK; + } else if (_data->getRTTI().isExactly(TransformConstraintData::rtti)) { + return SPINE_CONSTRAINT_TRANSFORM; + } else if (_data->getRTTI().isExactly(PathConstraintData::rtti)) { + return SPINE_CONSTRAINT_PATH; + } else { + return SPINE_CONSTRAINT_IK; + } +} + +const utf8 *spine_constraint_data_get_name(spine_constraint_data data) { + if (data == nullptr) return nullptr; + ConstraintData *_data = (ConstraintData *) data; + return (utf8 *) _data->getName().buffer(); +} + +uint64_t spine_constraint_data_get_order(spine_constraint_data data) { + if (data == nullptr) return 0; + ConstraintData *_data = (ConstraintData *) data; + return (uint64_t) _data->getOrder(); +} + +void spine_constraint_data_set_order(spine_constraint_data data, uint64_t order) { + if (data == nullptr) return; + ConstraintData *_data = (ConstraintData *) data; + _data->setOrder((size_t) order); +} + +int32_t spine_constraint_data_get_is_skin_required(spine_constraint_data data) { + if (data == nullptr) return 0; + ConstraintData *_data = (ConstraintData *) data; + return _data->isSkinRequired() ? -1 : 0; +} + +void spine_constraint_data_set_is_skin_required(spine_constraint_data data, int32_t isSkinRequired) { + if (data == nullptr) return; + ConstraintData *_data = (ConstraintData *) data; + _data->setSkinRequired(isSkinRequired); +} + +// IkConstraintData +int32_t spine_ik_constraint_data_get_num_bones(spine_ik_constraint_data data) { + if (data == nullptr) return 0; + IkConstraintData *_data = (IkConstraintData *) data; + return (int32_t) _data->getBones().size(); +} + +spine_bone_data *spine_ik_constraint_data_get_bones(spine_ik_constraint_data data) { + if (data == nullptr) return nullptr; + IkConstraintData *_data = (IkConstraintData *) data; + return (spine_bone_data *) _data->getBones().buffer(); +} + +spine_bone_data spine_ik_constraint_data_get_target(spine_ik_constraint_data data) { + if (data == nullptr) return nullptr; + IkConstraintData *_data = (IkConstraintData *) data; + return (spine_bone_data) _data->getTarget(); +} + +void spine_ik_constraint_data_set_target(spine_ik_constraint_data data, spine_bone_data target) { + if (data == nullptr) return; + IkConstraintData *_data = (IkConstraintData *) data; + _data->setTarget((BoneData *) target); +} + +int32_t spine_ik_constraint_data_get_bend_direction(spine_ik_constraint_data data) { + if (data == nullptr) return 1; + IkConstraintData *_data = (IkConstraintData *) data; + return _data->getBendDirection(); +} + +void spine_ik_constraint_data_set_bend_direction(spine_ik_constraint_data data, int32_t bendDirection) { + if (data == nullptr) return; + IkConstraintData *_data = (IkConstraintData *) data; + _data->setBendDirection(bendDirection); +} + +int32_t spine_ik_constraint_data_get_compress(spine_ik_constraint_data data) { + if (data == nullptr) return 0; + IkConstraintData *_data = (IkConstraintData *) data; + return _data->getCompress() ? -1 : 0; +} + +void spine_ik_constraint_data_set_compress(spine_ik_constraint_data data, int32_t compress) { + if (data == nullptr) return; + IkConstraintData *_data = (IkConstraintData *) data; + _data->setCompress(compress); +} + +int32_t spine_ik_constraint_data_get_stretch(spine_ik_constraint_data data) { + if (data == nullptr) return 0; + IkConstraintData *_data = (IkConstraintData *) data; + return _data->getStretch() ? -1 : 0; +} + +void spine_ik_constraint_data_set_stretch(spine_ik_constraint_data data, int32_t stretch) { + if (data == nullptr) return; + IkConstraintData *_data = (IkConstraintData *) data; + _data->setStretch(stretch); +} + +int32_t spine_ik_constraint_data_get_uniform(spine_ik_constraint_data data) { + if (data == nullptr) return 0; + IkConstraintData *_data = (IkConstraintData *) data; + return _data->getUniform() ? -1 : 0; +} + +float spine_ik_constraint_data_get_mix(spine_ik_constraint_data data) { + if (data == nullptr) return 0; + IkConstraintData *_data = (IkConstraintData *) data; + return _data->getMix(); +} + +void spine_ik_constraint_data_set_mix(spine_ik_constraint_data data, float mix) { + if (data == nullptr) return; + IkConstraintData *_data = (IkConstraintData *) data; + _data->setMix(mix); +} + +float spine_ik_constraint_data_get_softness(spine_ik_constraint_data data) { + if (data == nullptr) return 0; + IkConstraintData *_data = (IkConstraintData *) data; + return _data->getSoftness(); +} + +void spine_ik_constraint_data_set_softness(spine_ik_constraint_data data, float softness) { + if (data == nullptr) return; + IkConstraintData *_data = (IkConstraintData *) data; + _data->setSoftness(softness); +} + +// IKConstraint +void spine_ik_constraint_update(spine_ik_constraint constraint) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->update(); +} + +int32_t spine_ik_constraint_get_order(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->getOrder(); +} + +spine_ik_constraint_data spine_ik_constraint_get_data(spine_ik_constraint constraint) { + if (constraint == nullptr) return nullptr; + IkConstraint *_constraint = (IkConstraint *) constraint; + return (spine_ik_constraint_data) &_constraint->getData(); +} + +int32_t spine_ik_constraint_get_num_bones(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return (int32_t) _constraint->getBones().size(); +} + +spine_bone *spine_ik_constraint_get_bones(spine_ik_constraint constraint) { + if (constraint == nullptr) return nullptr; + IkConstraint *_constraint = (IkConstraint *) constraint; + return (spine_bone *) _constraint->getBones().buffer(); +} + +spine_bone spine_ik_constraint_get_target(spine_ik_constraint constraint) { + if (constraint == nullptr) return nullptr; + IkConstraint *_constraint = (IkConstraint *) constraint; + return (spine_bone) _constraint->getTarget(); +} + +void spine_ik_constraint_set_target(spine_ik_constraint constraint, spine_bone target) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setTarget((Bone *) target); +} + +int32_t spine_ik_constraint_get_bend_direction(spine_ik_constraint constraint) { + if (constraint == nullptr) return 1; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->getBendDirection(); +} + +void spine_ik_constraint_set_bend_direction(spine_ik_constraint constraint, int32_t bendDirection) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setBendDirection(bendDirection); +} + +int32_t spine_ik_constraint_get_compress(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->getCompress() ? -1 : 0; +} + +void spine_ik_constraint_set_compress(spine_ik_constraint constraint, int32_t compress) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setCompress(compress); +} + +int32_t spine_ik_constraint_get_stretch(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->getStretch() ? -1 : 0; +} + +void spine_ik_constraint_set_stretch(spine_ik_constraint constraint, int32_t stretch) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setStretch(stretch); +} + +float spine_ik_constraint_get_mix(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->getMix(); +} + +void spine_ik_constraint_set_mix(spine_ik_constraint constraint, float mix) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setMix(mix); +} + +float spine_ik_constraint_get_softness(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->getSoftness(); +} + +void spine_ik_constraint_set_softness(spine_ik_constraint constraint, float softness) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setSoftness(softness); +} + +int32_t spine_ik_constraint_get_is_active(spine_ik_constraint constraint) { + if (constraint == nullptr) return 0; + IkConstraint *_constraint = (IkConstraint *) constraint; + return _constraint->isActive() ? -1 : 0; +} + +void spine_ik_constraint_set_is_active(spine_ik_constraint constraint, int32_t isActive) { + if (constraint == nullptr) return; + IkConstraint *_constraint = (IkConstraint *) constraint; + _constraint->setActive(isActive); +} + +// TransformConstraintData +int32_t spine_transform_constraint_data_get_num_bones(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return (int32_t) _data->getBones().size(); +} + +spine_bone_data *spine_transform_constraint_data_get_bones(spine_transform_constraint_data data) { + if (data == nullptr) return nullptr; + TransformConstraintData *_data = (TransformConstraintData *) data; + return (spine_bone_data *) _data->getBones().buffer(); +} + +spine_bone_data spine_transform_constraint_data_get_target(spine_transform_constraint_data data) { + if (data == nullptr) return nullptr; + TransformConstraintData *_data = (TransformConstraintData *) data; + return (spine_bone_data) _data->getTarget(); +} + +void spine_transform_constraint_data_set_target(spine_transform_constraint_data data, spine_bone_data target) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setTarget((BoneData *) target); +} + +float spine_transform_constraint_data_get_mix_rotate(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getMixRotate(); +} + +void spine_transform_constraint_data_set_mix_rotate(spine_transform_constraint_data data, float mixRotate) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setMixRotate(mixRotate); +} + +float spine_transform_constraint_data_get_mix_x(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getMixX(); +} + +void spine_transform_constraint_data_set_mix_x(spine_transform_constraint_data data, float mixX) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setMixX(mixX); +} + +float spine_transform_constraint_data_get_mix_y(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getMixY(); +} + +void spine_transform_constraint_data_set_mix_y(spine_transform_constraint_data data, float mixY) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setMixY(mixY); +} + +float spine_transform_constraint_data_get_mix_scale_x(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getMixScaleX(); +} + +void spine_transform_constraint_data_set_mix_scale_x(spine_transform_constraint_data data, float mixScaleX) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setMixScaleX(mixScaleX); +} + +float spine_transform_constraint_data_get_mix_scale_y(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getMixScaleY(); +} + +void spine_transform_constraint_data_set_mix_scale_y(spine_transform_constraint_data data, float mixScaleY) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setMixScaleY(mixScaleY); +} + +float spine_transform_constraint_data_get_mix_shear_y(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getMixShearY(); +} + +void spine_transform_constraint_data_set_mix_shear_y(spine_transform_constraint_data data, float mixShearY) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setMixShearY(mixShearY); +} + +float spine_transform_constraint_data_get_offset_rotation(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getOffsetRotation(); +} + +void spine_transform_constraint_data_set_offset_rotation(spine_transform_constraint_data data, float offsetRotation) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setOffsetRotation(offsetRotation); +} + +float spine_transform_constraint_data_get_offset_x(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getOffsetX(); +} + +void spine_transform_constraint_data_set_offset_x(spine_transform_constraint_data data, float offsetX) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setOffsetX(offsetX); +} + +float spine_transform_constraint_data_get_offset_y(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getOffsetY(); +} + +void spine_transform_constraint_data_set_offset_y(spine_transform_constraint_data data, float offsetY) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setOffsetY(offsetY); +} + +float spine_transform_constraint_data_get_offset_scale_x(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getOffsetScaleX(); +} + +void spine_transform_constraint_data_set_offset_scale_x(spine_transform_constraint_data data, float offsetScaleX) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setOffsetScaleX(offsetScaleX); +} + +float spine_transform_constraint_data_get_offset_scale_y(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getOffsetScaleY(); +} + +void spine_transform_constraint_data_set_offset_scale_y(spine_transform_constraint_data data, float offsetScaleY) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setOffsetScaleY(offsetScaleY); +} + +float spine_transform_constraint_data_get_offset_shear_y(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->getOffsetShearY(); +} + +void spine_transform_constraint_data_set_offset_shear_y(spine_transform_constraint_data data, float offsetShearY) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setOffsetShearY(offsetShearY); +} + +int32_t spine_transform_constraint_data_get_is_relative(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->isRelative() ? -1 : 0; +} + +void spine_transform_constraint_data_set_is_relative(spine_transform_constraint_data data, int32_t isRelative) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setRelative(isRelative); +} + +int32_t spine_transform_constraint_data_get_is_local(spine_transform_constraint_data data) { + if (data == nullptr) return 0; + TransformConstraintData *_data = (TransformConstraintData *) data; + return _data->isLocal() ? -1 : 0; +} + +void spine_transform_constraint_data_set_is_local(spine_transform_constraint_data data, int32_t isLocal) { + if (data == nullptr) return; + TransformConstraintData *_data = (TransformConstraintData *) data; + _data->setLocal(isLocal); +} + +// TransformConstraint +void spine_transform_constraint_update(spine_transform_constraint constraint) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->update(); +} + +int32_t spine_transform_constraint_get_order(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getOrder(); +} + +spine_transform_constraint_data spine_transform_constraint_get_data(spine_transform_constraint constraint) { + if (constraint == nullptr) return nullptr; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return (spine_transform_constraint_data) &_constraint->getData(); +} + +int32_t spine_transform_constraint_get_num_bones(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return (int32_t) _constraint->getBones().size(); +} + +spine_bone *spine_transform_constraint_get_bones(spine_transform_constraint constraint) { + if (constraint == nullptr) return nullptr; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return (spine_bone *) _constraint->getBones().buffer(); +} + +spine_bone spine_transform_constraint_get_target(spine_transform_constraint constraint) { + if (constraint == nullptr) return nullptr; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return (spine_bone) _constraint->getTarget(); +} + +void spine_transform_constraint_set_target(spine_transform_constraint constraint, spine_bone target) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setTarget((Bone *) target); +} + +float spine_transform_constraint_get_mix_rotate(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getMixRotate(); +} + +void spine_transform_constraint_set_mix_rotate(spine_transform_constraint constraint, float mixRotate) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setMixRotate(mixRotate); +} + +float spine_transform_constraint_get_mix_x(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getMixX(); +} + +void spine_transform_constraint_set_mix_x(spine_transform_constraint constraint, float mixX) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setMixX(mixX); +} + +float spine_transform_constraint_get_mix_y(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getMixY(); +} + +void spine_transform_constraint_set_mix_y(spine_transform_constraint constraint, float mixY) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setMixY(mixY); +} + +float spine_transform_constraint_get_mix_scale_x(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getMixScaleX(); +} + +void spine_transform_constraint_set_mix_scale_x(spine_transform_constraint constraint, float mixScaleX) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setMixScaleX(mixScaleX); +} + +float spine_transform_constraint_get_mix_scale_y(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getMixScaleY(); +} + +void spine_transform_constraint_set_mix_scale_y(spine_transform_constraint constraint, float mixScaleY) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setMixScaleY(mixScaleY); +} + +float spine_transform_constraint_get_mix_shear_y(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->getMixShearY(); +} + +void spine_transform_constraint_set_mix_shear_y(spine_transform_constraint constraint, float mixShearY) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setMixShearY(mixShearY); +} + +float spine_transform_constraint_get_is_active(spine_transform_constraint constraint) { + if (constraint == nullptr) return 0; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + return _constraint->isActive() ? -1 : 0; +} + +void spine_transform_constraint_set_is_active(spine_transform_constraint constraint, int32_t isActive) { + if (constraint == nullptr) return; + TransformConstraint *_constraint = (TransformConstraint *) constraint; + _constraint->setActive(isActive); +} + +// PathConstraintData +int32_t spine_path_constraint_data_get_num_bones(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return (int32_t) _data->getBones().size(); +} + +spine_bone_data *spine_path_constraint_data_get_bones(spine_path_constraint_data data) { + if (data == nullptr) return nullptr; + PathConstraintData *_data = (PathConstraintData *) data; + return (spine_bone_data *) _data->getBones().buffer(); +} + +spine_slot_data spine_path_constraint_data_get_target(spine_path_constraint_data data) { + if (data == nullptr) return nullptr; + PathConstraintData *_data = (PathConstraintData *) data; + return (spine_slot_data) _data->getTarget(); +} + +void spine_path_constraint_data_set_target(spine_path_constraint_data data, spine_slot_data target) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setTarget((SlotData *) target); +} + +spine_position_mode spine_path_constraint_data_get_position_mode(spine_path_constraint_data data) { + if (data == nullptr) return SPINE_POSITION_MODE_FIXED; + PathConstraintData *_data = (PathConstraintData *) data; + return (spine_position_mode) _data->getPositionMode(); +} + +void spine_path_constraint_data_set_position_mode(spine_path_constraint_data data, spine_position_mode positionMode) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setPositionMode((PositionMode) positionMode); +} + +spine_spacing_mode spine_path_constraint_data_get_spacing_mode(spine_path_constraint_data data) { + if (data == nullptr) return SPINE_SPACING_MODE_LENGTH; + PathConstraintData *_data = (PathConstraintData *) data; + return (spine_spacing_mode) _data->getSpacingMode(); +} + +void spine_path_constraint_data_set_spacing_mode(spine_path_constraint_data data, spine_spacing_mode spacingMode) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setSpacingMode((SpacingMode) spacingMode); +} + +spine_rotate_mode spine_path_constraint_data_get_rotate_mode(spine_path_constraint_data data) { + if (data == nullptr) return SPINE_ROTATE_MODE_TANGENT; + PathConstraintData *_data = (PathConstraintData *) data; + return (spine_rotate_mode) _data->getRotateMode(); +} + +void spine_path_constraint_data_set_rotate_mode(spine_path_constraint_data data, spine_rotate_mode rotateMode) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setRotateMode((RotateMode) rotateMode); +} + +float spine_path_constraint_data_get_offset_rotation(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return _data->getOffsetRotation(); +} + +void spine_path_constraint_data_set_offset_rotation(spine_path_constraint_data data, float offsetRotation) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setOffsetRotation(offsetRotation); +} + +float spine_path_constraint_data_get_position(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return _data->getPosition(); +} + +void spine_path_constraint_data_set_position(spine_path_constraint_data data, float position) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setPosition(position); +} + +float spine_path_constraint_data_get_spacing(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return _data->getSpacing(); +} + +void spine_path_constraint_data_set_spacing(spine_path_constraint_data data, float spacing) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setSpacing(spacing); +} + +float spine_path_constraint_data_get_mix_rotate(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return _data->getMixRotate(); +} + +void spine_path_constraint_data_set_mix_rotate(spine_path_constraint_data data, float mixRotate) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setMixRotate(mixRotate); +} + +float spine_path_constraint_data_get_mix_x(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return _data->getMixX(); +} + +void spine_path_constraint_data_set_mix_x(spine_path_constraint_data data, float mixX) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setMixX(mixX); +} + +float spine_path_constraint_data_get_mix_y(spine_path_constraint_data data) { + if (data == nullptr) return 0; + PathConstraintData *_data = (PathConstraintData *) data; + return _data->getMixY(); +} + +void spine_path_constraint_data_set_mix_y(spine_path_constraint_data data, float mixY) { + if (data == nullptr) return; + PathConstraintData *_data = (PathConstraintData *) data; + _data->setMixY(mixY); +} + +// PathConstraint +void spine_path_constraint_update(spine_path_constraint constraint) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->update(); +} + +int32_t spine_path_constraint_get_order(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->getOrder(); +} + +spine_path_constraint_data spine_path_constraint_get_data(spine_path_constraint constraint) { + if (constraint == nullptr) return nullptr; + PathConstraint *_constraint = (PathConstraint *) constraint; + return (spine_path_constraint_data) &_constraint->getData(); +} + +int32_t spine_path_constraint_get_num_bones(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return (int32_t) _constraint->getBones().size(); +} + +spine_bone *spine_path_constraint_get_bones(spine_path_constraint constraint) { + if (constraint == nullptr) return nullptr; + PathConstraint *_constraint = (PathConstraint *) constraint; + return (spine_bone *) _constraint->getBones().buffer(); +} + +spine_slot spine_path_constraint_get_target(spine_path_constraint constraint) { + if (constraint == nullptr) return nullptr; + PathConstraint *_constraint = (PathConstraint *) constraint; + return (spine_slot) _constraint->getTarget(); +} + +void spine_path_constraint_set_target(spine_path_constraint constraint, spine_slot target) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setTarget((Slot *) target); +} + +float spine_path_constraint_get_position(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->getPosition(); +} + +void spine_path_constraint_set_position(spine_path_constraint constraint, float position) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setPosition(position); +} + +float spine_path_constraint_get_spacing(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->getSpacing(); +} + +void spine_path_constraint_set_spacing(spine_path_constraint constraint, float spacing) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setSpacing(spacing); +} + +float spine_path_constraint_get_mix_rotate(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->getMixRotate(); +} + +void spine_path_constraint_set_mix_rotate(spine_path_constraint constraint, float mixRotate) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setMixRotate(mixRotate); +} + +float spine_path_constraint_get_mix_x(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->getMixX(); +} + +void spine_path_constraint_set_mix_x(spine_path_constraint constraint, float mixX) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setMixX(mixX); +} + +float spine_path_constraint_get_mix_y(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->getMixY(); +} + +void spine_path_constraint_set_mix_y(spine_path_constraint constraint, float mixY) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setMixY(mixY); +} + +int32_t spine_path_constraint_get_is_active(spine_path_constraint constraint) { + if (constraint == nullptr) return 0; + PathConstraint *_constraint = (PathConstraint *) constraint; + return _constraint->isActive() ? -1 : 0; +} + +void spine_path_constraint_set_is_active(spine_path_constraint constraint, int32_t isActive) { + if (constraint == nullptr) return; + PathConstraint *_constraint = (PathConstraint *) constraint; + _constraint->setActive(isActive); +} + +// Sequence +void spine_sequence_apply(spine_sequence sequence, spine_slot slot, spine_attachment attachment) { + if (sequence == nullptr) return; + Sequence *_sequence = (Sequence *) sequence; + _sequence->apply((Slot *) slot, (Attachment *) attachment); +} + +const utf8 *spine_sequence_get_path(spine_sequence sequence, const utf8 *basePath, int32_t index) { + if (sequence == nullptr) return nullptr; + Sequence *_sequence = (Sequence *) sequence; + return (utf8 *) strdup(_sequence->getPath(basePath, index).buffer()); +} + +int32_t spine_sequence_get_id(spine_sequence sequence) { + if (sequence == nullptr) return 0; + Sequence *_sequence = (Sequence *) sequence; + return _sequence->getId(); +} + +void spine_sequence_set_id(spine_sequence sequence, int32_t id) { + if (sequence == nullptr) return; + Sequence *_sequence = (Sequence *) sequence; + _sequence->setId(id); +} + +int32_t spine_sequence_get_start(spine_sequence sequence) { + if (sequence == nullptr) return 0; + Sequence *_sequence = (Sequence *) sequence; + return _sequence->getStart(); +} + +void spine_sequence_set_start(spine_sequence sequence, int32_t start) { + if (sequence == nullptr) return; + Sequence *_sequence = (Sequence *) sequence; + _sequence->setStart(start); +} + +int32_t spine_sequence_get_digits(spine_sequence sequence) { + if (sequence == nullptr) return 0; + Sequence *_sequence = (Sequence *) sequence; + return _sequence->getDigits(); +} + +void spine_sequence_set_digits(spine_sequence sequence, int32_t digits) { + if (sequence == nullptr) return; + Sequence *_sequence = (Sequence *) sequence; + _sequence->setDigits(digits); +} + +int32_t spine_sequence_get_setup_index(spine_sequence sequence) { + if (sequence == nullptr) return 0; + Sequence *_sequence = (Sequence *) sequence; + return _sequence->getSetupIndex(); +} + +void spine_sequence_set_setup_index(spine_sequence sequence, int32_t setupIndex) { + if (sequence == nullptr) return; + Sequence *_sequence = (Sequence *) sequence; + _sequence->setSetupIndex(setupIndex); +} + +int32_t spine_sequence_get_num_regions(spine_sequence sequence) { + if (sequence == nullptr) return 0; + Sequence *_sequence = (Sequence *) sequence; + return (int32_t) _sequence->getRegions().size(); +} + +spine_texture_region *spine_sequence_get_regions(spine_sequence sequence) { + if (sequence == nullptr) return nullptr; + Sequence *_sequence = (Sequence *) sequence; + return (spine_texture_region *) _sequence->getRegions().buffer(); +} + +// TextureRegion +void *spine_texture_region_get_texture(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return nullptr; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->rendererObject; +} + +void spine_texture_region_set_texture(spine_texture_region textureRegion, void *texture) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->rendererObject = texture; +} + +float spine_texture_region_get_u(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->u; +} + +void spine_texture_region_set_u(spine_texture_region textureRegion, float u) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->u = u; +} + +float spine_texture_region_get_v(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->v; +} +void spine_texture_region_set_v(spine_texture_region textureRegion, float v) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->v = v; +} +float spine_texture_region_get_u2(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->u2; +} + +void spine_texture_region_set_u2(spine_texture_region textureRegion, float u2) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->u2 = u2; +} + +float spine_texture_region_get_v2(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->v2; +} + +void spine_texture_region_set_v2(spine_texture_region textureRegion, float v2) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->v2 = v2; +} + +int32_t spine_texture_region_get_degrees(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->degrees; +} + +void spine_texture_region_set_degrees(spine_texture_region textureRegion, int32_t degrees) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->degrees = degrees; +} + +float spine_texture_region_get_offset_x(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->offsetX; +} + +void spine_texture_region_set_offset_x(spine_texture_region textureRegion, float offsetX) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->offsetX = offsetX; +} + +float spine_texture_region_get_offset_y(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->offsetY; +} + +void spine_texture_region_set_offset_y(spine_texture_region textureRegion, float offsetY) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->offsetY = offsetY; +} + +int32_t spine_texture_region_get_width(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->width; +} + +void spine_texture_region_set_width(spine_texture_region textureRegion, int32_t width) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->width = width; +} + +int32_t spine_texture_region_get_height(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->height; +} + +void spine_texture_region_set_height(spine_texture_region textureRegion, int32_t height) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->height = height; +} + +int32_t spine_texture_region_get_original_width(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->originalWidth; +} + +void spine_texture_region_set_original_width(spine_texture_region textureRegion, int32_t originalWidth) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->originalWidth = originalWidth; +} + +int32_t spine_texture_region_get_original_height(spine_texture_region textureRegion) { + if (textureRegion == nullptr) return 0; + TextureRegion *_region = (TextureRegion *) textureRegion; + return _region->originalHeight; +} + +void spine_texture_region_set_original_height(spine_texture_region textureRegion, int32_t originalHeight) { + if (textureRegion == nullptr) return; + TextureRegion *_region = (TextureRegion *) textureRegion; + _region->originalHeight = originalHeight; +} diff --git a/spine-flutter/src/spine_flutter.h b/spine-flutter/src/spine_flutter.h new file mode 100644 index 000000000..720fd2acb --- /dev/null +++ b/spine-flutter/src/spine_flutter.h @@ -0,0 +1,856 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated September 24, 2021. Replaces all prior versions. + * + * Copyright (c) 2013-2021, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef SPINE_FLUTTER +#define SPINE_FLUTTER + +#include + +#ifdef __cplusplus +#if _WIN32 +#define SPINE_FLUTTER_EXPORT extern "C" __declspec(dllexport) +#else +#ifdef __EMSCRIPTEN__ +#define SPINE_FLUTTER_EXPORT extern "C" __attribute__((used)) +#else +#define SPINE_FLUTTER_EXPORT extern "C" +#endif +#endif +#else +#if _WIN32 +#define SPINE_FLUTTER_EXPORT __declspec(dllexport) +#else +#ifdef __EMSCRIPTEN__ +#define SPINE_FLUTTER_EXPORT __attribute__((used)) +#else +#define SPINE_FLUTTER_EXPORT +#endif +#endif +#endif + +#define SPINE_OPAQUE_TYPE(name) \ + typedef struct name##_wrapper { \ + } name##_wrapper; \ + typedef name##_wrapper *name; + +SPINE_OPAQUE_TYPE(spine_skeleton) +SPINE_OPAQUE_TYPE(spine_skeleton_data) +SPINE_OPAQUE_TYPE(spine_bone) +SPINE_OPAQUE_TYPE(spine_bone_data) +SPINE_OPAQUE_TYPE(spine_slot) +SPINE_OPAQUE_TYPE(spine_slot_data) +SPINE_OPAQUE_TYPE(spine_skin) +SPINE_OPAQUE_TYPE(spine_attachment) +SPINE_OPAQUE_TYPE(spine_region_attachment) +SPINE_OPAQUE_TYPE(spine_vertex_attachment) +SPINE_OPAQUE_TYPE(spine_mesh_attachment) +SPINE_OPAQUE_TYPE(spine_clipping_attachment) +SPINE_OPAQUE_TYPE(spine_bounding_box_attachment) +SPINE_OPAQUE_TYPE(spine_path_attachment) +SPINE_OPAQUE_TYPE(spine_point_attachment) +SPINE_OPAQUE_TYPE(spine_texture_region) +SPINE_OPAQUE_TYPE(spine_sequence) +SPINE_OPAQUE_TYPE(spine_constraint) +SPINE_OPAQUE_TYPE(spine_constraint_data) +SPINE_OPAQUE_TYPE(spine_ik_constraint) +SPINE_OPAQUE_TYPE(spine_ik_constraint_data) +SPINE_OPAQUE_TYPE(spine_transform_constraint) +SPINE_OPAQUE_TYPE(spine_transform_constraint_data) +SPINE_OPAQUE_TYPE(spine_path_constraint) +SPINE_OPAQUE_TYPE(spine_path_constraint_data) +SPINE_OPAQUE_TYPE(spine_animation_state) +SPINE_OPAQUE_TYPE(spine_animation_state_data) +SPINE_OPAQUE_TYPE(spine_animation_state_events) +SPINE_OPAQUE_TYPE(spine_event) +SPINE_OPAQUE_TYPE(spine_event_data) +SPINE_OPAQUE_TYPE(spine_track_entry) +SPINE_OPAQUE_TYPE(spine_animation) +SPINE_OPAQUE_TYPE(spine_atlas) +SPINE_OPAQUE_TYPE(spine_skeleton_data_result) +SPINE_OPAQUE_TYPE(spine_render_command) +SPINE_OPAQUE_TYPE(spine_bounds) +SPINE_OPAQUE_TYPE(spine_color) +SPINE_OPAQUE_TYPE(spine_vector) +SPINE_OPAQUE_TYPE(spine_skeleton_drawable) +SPINE_OPAQUE_TYPE(spine_skin_entry) +SPINE_OPAQUE_TYPE(spine_skin_entries) + +typedef char utf8; + +typedef enum spine_blend_mode { + SPINE_BLEND_MODE_NORMAL = 0, + SPINE_BLEND_MODE_ADDITIVE, + SPINE_BLEND_MODE_MULTIPLY, + SPINE_BLEND_MODE_SCREEN +} spine_blend_mode; + +typedef enum spine_mix_blend { + SPINE_MIX_BLEND_SETUP = 0, + SPINE_MIX_BLEND_FIRST, + SPINE_MIX_BLEND_REPLACE, + SPINE_MIX_BLEND_ADD +} spine_mix_blend; + +typedef enum spine_event_type { + SPINE_EVENT_TYPE_START = 0, + SPINE_EVENT_TYPE_INTERRUPT, + SPINE_EVENT_TYPE_END, + SPINE_EVENT_TYPE_COMPLETE, + SPINE_EVENT_TYPE_DISPOSE, + SPINE_EVENT_TYPE_EVENT +} spine_event_type; + +typedef enum spine_attachment_type { + SPINE_ATTACHMENT_REGION = 0, + SPINE_ATTACHMENT_MESH, + SPINE_ATTACHMENT_CLIPPING, + SPINE_ATTACHMENT_BOUNDING_BOX, + SPINE_ATTACHMENT_PATH, + SPINE_ATTACHMENT_POINT, +} spine_attachment_type; + +typedef enum spine_constraint_type { + SPINE_CONSTRAINT_IK, + SPINE_CONSTRAINT_TRANSFORM, + SPINE_CONSTRAINT_PATH +} spine_constraint_type; + +typedef enum spine_transform_mode { + SPINE_TRANSFORM_MODE_NORMAL = 0, + SPINE_TRANSFORM_ONLY_TRANSLATION, + SPINE_TRANSFORM_NO_ROTATION_OR_REFLECTION, + SPINE_TRANSFORM_NO_SCALE, + SPINE_TRANSFORM_NO_SCALE_OR_REFLECTION +} spine_transform_mode; + +typedef enum spine_position_mode { + SPINE_POSITION_MODE_FIXED = 0, + SPINE_POSITION_MODE_PERCENT +} spine_position_mode; + +typedef enum spine_spacing_mode { + SPINE_SPACING_MODE_LENGTH = 0, + SPINE_SPACING_MODE_FIXED, + SPINE_SPACING_MODE_PERCENT, + SPINE_SPACING_MODE_PROPORTIONAL +} spine_spacing_mode; + +typedef enum spine_rotate_mode { + SPINE_ROTATE_MODE_TANGENT = 0, + SPINE_ROTATE_MODE_CHAIN, + SPINE_ROTATE_MODE_CHAIN_SCALE +} spine_rotate_mode; + +SPINE_FLUTTER_EXPORT int32_t spine_major_version(); +SPINE_FLUTTER_EXPORT int32_t spine_minor_version(); +SPINE_FLUTTER_EXPORT void spine_enable_debug_extension(int32_t enable); +SPINE_FLUTTER_EXPORT void spine_report_leaks(); + +SPINE_FLUTTER_EXPORT float spine_color_get_r(spine_color color); +SPINE_FLUTTER_EXPORT float spine_color_get_g(spine_color color); +SPINE_FLUTTER_EXPORT float spine_color_get_b(spine_color color); +SPINE_FLUTTER_EXPORT float spine_color_get_a(spine_color color); + +SPINE_FLUTTER_EXPORT float spine_bounds_get_x(spine_bounds bounds); +SPINE_FLUTTER_EXPORT float spine_bounds_get_y(spine_bounds bounds); +SPINE_FLUTTER_EXPORT float spine_bounds_get_width(spine_bounds bounds); +SPINE_FLUTTER_EXPORT float spine_bounds_get_height(spine_bounds bounds); + +SPINE_FLUTTER_EXPORT float spine_vector_get_x(spine_vector vector); +SPINE_FLUTTER_EXPORT float spine_vector_get_y(spine_vector vector); + +SPINE_FLUTTER_EXPORT spine_atlas spine_atlas_load(const utf8 *atlasData); +SPINE_FLUTTER_EXPORT int32_t spine_atlas_get_num_image_paths(spine_atlas atlas); +SPINE_FLUTTER_EXPORT utf8 *spine_atlas_get_image_path(spine_atlas atlas, int32_t index); +SPINE_FLUTTER_EXPORT utf8 *spine_atlas_get_error(spine_atlas atlas); +SPINE_FLUTTER_EXPORT void spine_atlas_dispose(spine_atlas atlas); + +SPINE_FLUTTER_EXPORT spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const utf8 *skeletonData); +SPINE_FLUTTER_EXPORT spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length); +SPINE_FLUTTER_EXPORT utf8 *spine_skeleton_data_result_get_error(spine_skeleton_data_result result); +SPINE_FLUTTER_EXPORT spine_skeleton_data spine_skeleton_data_result_get_data(spine_skeleton_data_result result); +SPINE_FLUTTER_EXPORT void spine_skeleton_data_result_dispose(spine_skeleton_data_result result); +SPINE_FLUTTER_EXPORT spine_bone_data spine_skeleton_data_find_bone(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_slot_data spine_skeleton_data_find_slot(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_skin spine_skeleton_data_find_skin(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_event_data spine_skeleton_data_find_event(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_animation spine_skeleton_data_find_animation(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_ik_constraint_data spine_skeleton_data_find_ik_constraint(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_transform_constraint_data spine_skeleton_data_find_transform_constraint(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT spine_path_constraint_data spine_skeleton_data_find_path_constraint(spine_skeleton_data data, const utf8 *name); +SPINE_FLUTTER_EXPORT const utf8 *spine_skeleton_data_get_name(spine_skeleton_data data); +// OMITTED setName() +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_bones(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_bone_data *spine_skeleton_data_get_bones(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_slots(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_slot_data *spine_skeleton_data_get_slots(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_skins(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_skin *spine_skeleton_data_get_skins(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_skin spine_skeleton_data_get_default_skin(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT void spine_skeleton_data_set_default_skin(spine_skeleton_data data, spine_skin skin); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_events(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_event_data *spine_skeleton_data_get_events(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_animations(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_animation *spine_skeleton_data_get_animations(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_ik_constraints(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_ik_constraint_data *spine_skeleton_data_get_ik_constraints(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_transform_constraints(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_transform_constraint_data *spine_skeleton_data_get_transform_constraints(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_data_get_num_path_constraints(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT spine_path_constraint_data *spine_skeleton_data_get_path_constraints(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT float spine_skeleton_data_get_x(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT void spine_skeleton_data_set_x(spine_skeleton_data data, float x); +SPINE_FLUTTER_EXPORT float spine_skeleton_data_get_y(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT void spine_skeleton_data_set_y(spine_skeleton_data data, float y); +SPINE_FLUTTER_EXPORT float spine_skeleton_data_get_width(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT void spine_skeleton_data_set_width(spine_skeleton_data data, float width); +SPINE_FLUTTER_EXPORT float spine_skeleton_data_get_height(spine_skeleton_data data); +SPINE_FLUTTER_EXPORT void spine_skeleton_data_set_height(spine_skeleton_data data, float height); +SPINE_FLUTTER_EXPORT const utf8 *spine_skeleton_data_get_version(spine_skeleton_data data); +// OMITTED setVersion() +SPINE_FLUTTER_EXPORT const utf8 *spine_skeleton_data_get_hash(spine_skeleton_data data); +// OMITTED setHash() +SPINE_FLUTTER_EXPORT const utf8 *spine_skeleton_data_get_images_path(spine_skeleton_data data); +// OMITTED setImagesPath() +SPINE_FLUTTER_EXPORT const utf8 *spine_skeleton_data_get_audio_path(spine_skeleton_data data); +// OMITTED setAudioPath() +SPINE_FLUTTER_EXPORT float spine_skeleton_data_get_fps(spine_skeleton_data data); +// OMITTED setFps() +SPINE_FLUTTER_EXPORT void spine_skeleton_data_dispose(spine_skeleton_data data); + +SPINE_FLUTTER_EXPORT spine_skeleton_drawable spine_skeleton_drawable_create(spine_skeleton_data skeletonData); +SPINE_FLUTTER_EXPORT spine_render_command spine_skeleton_drawable_render(spine_skeleton_drawable drawable); +SPINE_FLUTTER_EXPORT void spine_skeleton_drawable_dispose(spine_skeleton_drawable drawable); +SPINE_FLUTTER_EXPORT spine_skeleton spine_skeleton_drawable_get_skeleton(spine_skeleton_drawable drawable); +SPINE_FLUTTER_EXPORT spine_animation_state spine_skeleton_drawable_get_animation_state(spine_skeleton_drawable drawable); +SPINE_FLUTTER_EXPORT spine_animation_state_data spine_skeleton_drawable_get_animation_state_data(spine_skeleton_drawable drawable); +SPINE_FLUTTER_EXPORT spine_animation_state_events spine_skeleton_drawable_get_animation_state_events(spine_skeleton_drawable drawable); + +SPINE_FLUTTER_EXPORT float *spine_render_command_get_positions(spine_render_command command); +SPINE_FLUTTER_EXPORT float *spine_render_command_get_uvs(spine_render_command command); +SPINE_FLUTTER_EXPORT int32_t *spine_render_command_get_colors(spine_render_command command); +SPINE_FLUTTER_EXPORT int32_t spine_render_command_get_num_vertices(spine_render_command command); +SPINE_FLUTTER_EXPORT uint16_t *spine_render_command_get_indices(spine_render_command command); +SPINE_FLUTTER_EXPORT int32_t spine_render_command_get_num_indices(spine_render_command command); +SPINE_FLUTTER_EXPORT int32_t spine_render_command_get_atlas_page(spine_render_command command); +SPINE_FLUTTER_EXPORT spine_blend_mode spine_render_command_get_blend_mode(spine_render_command command); +SPINE_FLUTTER_EXPORT spine_render_command spine_render_command_get_next(spine_render_command command); + +SPINE_FLUTTER_EXPORT const utf8 *spine_animation_get_name(spine_animation animation); +// OMITTED getTimelines() +// OMITTED hasTimeline() +SPINE_FLUTTER_EXPORT float spine_animation_get_duration(spine_animation animation); +// OMITTED setDuration() + +SPINE_FLUTTER_EXPORT spine_skeleton_data spine_animation_state_data_get_skeleton_data(spine_animation_state_data stateData); +SPINE_FLUTTER_EXPORT float spine_animation_state_data_get_default_mix(spine_animation_state_data stateData); +SPINE_FLUTTER_EXPORT void spine_animation_state_data_set_default_mix(spine_animation_state_data stateData, float defaultMix); +SPINE_FLUTTER_EXPORT void spine_animation_state_data_set_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to, float duration); +SPINE_FLUTTER_EXPORT float spine_animation_state_data_get_mix(spine_animation_state_data stateData, spine_animation from, spine_animation to); +SPINE_FLUTTER_EXPORT void spine_animation_state_data_set_mix_by_name(spine_animation_state_data stateData, const utf8 *fromName, const utf8 *toName, float duration); +SPINE_FLUTTER_EXPORT float spine_animation_state_data_get_mix_by_name(spine_animation_state_data stateData, const utf8 *fromName, const utf8 *toName); +SPINE_FLUTTER_EXPORT void spine_animation_state_data_clear(spine_animation_state_data stateData); + +SPINE_FLUTTER_EXPORT void spine_animation_state_update(spine_animation_state state, float delta); +SPINE_FLUTTER_EXPORT void spine_animation_state_apply(spine_animation_state state, spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_animation_state_clear_tracks(spine_animation_state state); +SPINE_FLUTTER_EXPORT void spine_animation_state_clear_track(spine_animation_state state, int32_t trackIndex); +SPINE_FLUTTER_EXPORT int32_t spine_animation_state_get_num_tracks(spine_animation_state state); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_set_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8 *animationName, int32_t loop); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_set_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_add_animation_by_name(spine_animation_state state, int32_t trackIndex, const utf8 *animationName, int32_t loop, float delay); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_add_animation(spine_animation_state state, int32_t trackIndex, spine_animation animation, int32_t loop, float delay); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_set_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_add_empty_animation(spine_animation_state state, int32_t trackIndex, float mixDuration, float delay); +SPINE_FLUTTER_EXPORT void spine_animation_state_set_empty_animations(spine_animation_state state, float mixDuration); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_get_current(spine_animation_state state, int32_t trackIndex); +SPINE_FLUTTER_EXPORT spine_animation_state_data spine_animation_state_get_data(spine_animation_state state); +SPINE_FLUTTER_EXPORT float spine_animation_state_get_time_scale(spine_animation_state state); +SPINE_FLUTTER_EXPORT void spine_animation_state_set_time_scale(spine_animation_state state, float timeScale); +// OMITTED setListener() +// OMITTED setListener() +// OMITTED disableQueue() +// OMITTED enableQueue() +// OMITTED setManualTrackEntryDisposal() +// OMITTED getManualTrackEntryDisposal() +SPINE_FLUTTER_EXPORT void spine_animation_state_dispose_track_entry(spine_animation_state state, spine_track_entry entry); + +SPINE_FLUTTER_EXPORT int32_t spine_animation_state_events_get_num_events(spine_animation_state_events events); +SPINE_FLUTTER_EXPORT spine_event_type spine_animation_state_events_get_event_type(spine_animation_state_events events, int32_t index); +SPINE_FLUTTER_EXPORT spine_track_entry spine_animation_state_events_get_track_entry(spine_animation_state_events events, int32_t index); +SPINE_FLUTTER_EXPORT spine_event spine_animation_state_events_get_event(spine_animation_state_events events, int32_t index); +SPINE_FLUTTER_EXPORT void spine_animation_state_events_reset(spine_animation_state_events events); + +SPINE_FLUTTER_EXPORT int32_t spine_track_entry_get_track_index(spine_track_entry entry); +SPINE_FLUTTER_EXPORT spine_animation spine_track_entry_get_animation(spine_track_entry entry); +SPINE_FLUTTER_EXPORT spine_track_entry spine_track_entry_get_previous(spine_track_entry entry); +SPINE_FLUTTER_EXPORT int32_t spine_track_entry_get_loop(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_loop(spine_track_entry entry, int32_t loop); +SPINE_FLUTTER_EXPORT int32_t spine_track_entry_get_hold_previous(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_hold_previous(spine_track_entry entry, int32_t holdPrevious); +SPINE_FLUTTER_EXPORT int32_t spine_track_entry_get_reverse(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_reverse(spine_track_entry entry, int32_t reverse); +SPINE_FLUTTER_EXPORT int32_t spine_track_entry_get_shortest_rotation(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_shortest_rotation(spine_track_entry entry, int32_t shortestRotation); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_delay(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_delay(spine_track_entry entry, float delay); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_track_time(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_track_time(spine_track_entry entry, float trackTime); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_track_end(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_track_end(spine_track_entry entry, float trackEnd); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_animation_start(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_animation_start(spine_track_entry entry, float animationStart); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_animation_end(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_animation_end(spine_track_entry entry, float animationEnd); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_animation_last(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_animation_last(spine_track_entry entry, float animationLast); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_animation_time(spine_track_entry entry); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_time_scale(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_time_scale(spine_track_entry entry, float timeScale); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_alpha(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_alpha(spine_track_entry entry, float alpha); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_event_threshold(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_event_threshold(spine_track_entry entry, float eventThreshold); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_attachment_threshold(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_attachment_threshold(spine_track_entry entry, float attachmentThreshold); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_draw_order_threshold(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_draw_order_threshold(spine_track_entry entry, float drawOrderThreshold); +SPINE_FLUTTER_EXPORT spine_track_entry spine_track_entry_get_next(spine_track_entry entry); +SPINE_FLUTTER_EXPORT int32_t spine_track_entry_is_complete(spine_track_entry entry); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_mix_time(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_mix_time(spine_track_entry entry, float mixTime); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_mix_duration(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_mix_duration(spine_track_entry entry, float mixDuration); +SPINE_FLUTTER_EXPORT spine_mix_blend spine_track_entry_get_mix_blend(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_set_mix_blend(spine_track_entry entry, spine_mix_blend mixBlend); +SPINE_FLUTTER_EXPORT spine_track_entry spine_track_entry_get_mixing_from(spine_track_entry entry); +SPINE_FLUTTER_EXPORT spine_track_entry spine_track_entry_get_mixing_to(spine_track_entry entry); +SPINE_FLUTTER_EXPORT void spine_track_entry_reset_rotation_directions(spine_track_entry entry); +SPINE_FLUTTER_EXPORT float spine_track_entry_get_track_complete(spine_track_entry entry); +// OMITTED setListener() +// OMITTED setListener() + +SPINE_FLUTTER_EXPORT void spine_skeleton_update_cache(spine_skeleton skeleton); +// OMITTED printUpdateCache() +SPINE_FLUTTER_EXPORT void spine_skeleton_update_world_transform(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_update_world_transform_bone(spine_skeleton skeleton, spine_bone parent); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_to_setup_pose(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_bones_to_setup_pose(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_slots_to_setup_pose(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_bone spine_skeleton_find_bone(spine_skeleton skeleton, const utf8 *boneName); +SPINE_FLUTTER_EXPORT spine_slot spine_skeleton_find_slot(spine_skeleton skeleton, const utf8 *slotName); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_skin_by_name(spine_skeleton skeleton, const utf8 *skinName); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_skin(spine_skeleton skeleton, spine_skin skin); +SPINE_FLUTTER_EXPORT spine_attachment spine_skeleton_get_attachment_by_name(spine_skeleton skeleton, const utf8 *slotName, const utf8 *attachmentName); +SPINE_FLUTTER_EXPORT spine_attachment spine_skeleton_get_attachment(spine_skeleton skeleton, int32_t slotIndex, const utf8 *attachmentName); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_attachment(spine_skeleton skeleton, const utf8 *slotName, const utf8 *attachmentName); +SPINE_FLUTTER_EXPORT spine_ik_constraint spine_skeleton_find_ik_constraint(spine_skeleton skeleton, const utf8 *constraintName); +SPINE_FLUTTER_EXPORT spine_transform_constraint spine_skeleton_find_transform_constraint(spine_skeleton skeleton, const utf8 *constraintName); +SPINE_FLUTTER_EXPORT spine_path_constraint spine_skeleton_find_path_constraint(spine_skeleton skeleton, const utf8 *constraintName); +SPINE_FLUTTER_EXPORT spine_bounds spine_skeleton_get_bounds(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_bone spine_skeleton_get_root_bone(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_skeleton_data spine_skeleton_get_data(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_get_num_bones(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_bone *spine_skeleton_get_bones(spine_skeleton skeleton); +// OMITTED getUpdateCacheList() +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_get_num_slots(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_slot *spine_skeleton_get_slots(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_get_num_draw_order(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_slot *spine_skeleton_get_draw_order(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_get_num_ik_constraints(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_ik_constraint *spine_skeleton_get_ik_constraints(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_get_num_transform_constraints(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_transform_constraint *spine_skeleton_get_transform_constraints(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT int32_t spine_skeleton_get_num_path_constraints(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_path_constraint *spine_skeleton_get_path_constraints(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_skin spine_skeleton_get_skin(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT spine_color spine_skeleton_get_color(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_color(spine_skeleton skeleton, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_position(spine_skeleton skeleton, float x, float y); +SPINE_FLUTTER_EXPORT float spine_skeleton_get_x(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_x(spine_skeleton skeleton, float x); +SPINE_FLUTTER_EXPORT float spine_skeleton_get_y(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_y(spine_skeleton skeleton, float y); +SPINE_FLUTTER_EXPORT float spine_skeleton_get_scale_x(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_scale_x(spine_skeleton skeleton, float scaleX); +SPINE_FLUTTER_EXPORT float spine_skeleton_get_scale_y(spine_skeleton skeleton); +SPINE_FLUTTER_EXPORT void spine_skeleton_set_scale_y(spine_skeleton skeleton, float scaleY); + +SPINE_FLUTTER_EXPORT const utf8 *spine_event_data_get_name(spine_event_data event); +SPINE_FLUTTER_EXPORT int32_t spine_event_data_get_int_value(spine_event_data event); +SPINE_FLUTTER_EXPORT void spine_event_data_set_int_value(spine_event_data event, int32_t value); +SPINE_FLUTTER_EXPORT float spine_event_data_get_float_value(spine_event_data event); +SPINE_FLUTTER_EXPORT void spine_event_data_set_float_value(spine_event_data event, float value); +SPINE_FLUTTER_EXPORT const utf8 *spine_event_data_get_string_value(spine_event_data event); +SPINE_FLUTTER_EXPORT void spine_event_data_set_string_value(spine_event_data event, const utf8 *value); +SPINE_FLUTTER_EXPORT const utf8 *spine_event_data_get_audio_path(spine_event_data event); +// OMITTED setAudioPath() +SPINE_FLUTTER_EXPORT float spine_event_data_get_volume(spine_event_data event); +SPINE_FLUTTER_EXPORT void spine_event_data_set_volume(spine_event_data event, float volume); +SPINE_FLUTTER_EXPORT float spine_event_data_get_balance(spine_event_data event); +SPINE_FLUTTER_EXPORT void spine_event_data_set_balance(spine_event_data event, float balance); + +SPINE_FLUTTER_EXPORT spine_event_data spine_event_get_data(spine_event event); +SPINE_FLUTTER_EXPORT float spine_event_get_time(spine_event event); +SPINE_FLUTTER_EXPORT int32_t spine_event_get_int_value(spine_event event); +SPINE_FLUTTER_EXPORT void spine_event_set_int_value(spine_event event, int32_t value); +SPINE_FLUTTER_EXPORT float spine_event_get_float_value(spine_event event); +SPINE_FLUTTER_EXPORT void spine_event_set_float_value(spine_event event, float value); +SPINE_FLUTTER_EXPORT const utf8 *spine_event_get_string_value(spine_event event); +SPINE_FLUTTER_EXPORT void spine_event_set_string_value(spine_event event, const utf8 *value); +SPINE_FLUTTER_EXPORT float spine_event_get_volume(spine_event event); +SPINE_FLUTTER_EXPORT void spine_event_set_volume(spine_event event, float volume); +SPINE_FLUTTER_EXPORT float spine_event_get_balance(spine_event event); +SPINE_FLUTTER_EXPORT void spine_event_set_balance(spine_event event, float balance); + +SPINE_FLUTTER_EXPORT int32_t spine_slot_data_get_index(spine_slot_data slot); +SPINE_FLUTTER_EXPORT const utf8 *spine_slot_data_get_name(spine_slot_data slot); +SPINE_FLUTTER_EXPORT spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot); +SPINE_FLUTTER_EXPORT spine_color spine_slot_data_get_color(spine_slot_data slot); +SPINE_FLUTTER_EXPORT void spine_slot_data_set_color(spine_slot_data slot, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT spine_color spine_slot_data_get_dark_color(spine_slot_data slot); +SPINE_FLUTTER_EXPORT void spine_slot_data_set_dark_color(spine_slot_data slot, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT int32_t spine_slot_data_has_dark_color(spine_slot_data slot); +SPINE_FLUTTER_EXPORT void spine_slot_data_set_has_dark_color(spine_slot_data slot, int32_t hasDarkColor); +SPINE_FLUTTER_EXPORT const utf8 *spine_slot_data_get_attachment_name(spine_slot_data slot); +SPINE_FLUTTER_EXPORT void spine_slot_data_set_attachment_name(spine_slot_data slot, const utf8 *attachmentName); +SPINE_FLUTTER_EXPORT spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot); +SPINE_FLUTTER_EXPORT void spine_slot_data_set_blend_mode(spine_slot_data slot, spine_blend_mode blendMode); + +SPINE_FLUTTER_EXPORT void spine_slot_set_to_setup_pose(spine_slot slot); +SPINE_FLUTTER_EXPORT spine_slot_data spine_slot_get_data(spine_slot slot); +SPINE_FLUTTER_EXPORT spine_bone spine_slot_get_bone(spine_slot slot); +SPINE_FLUTTER_EXPORT spine_skeleton spine_slot_get_skeleton(spine_slot slot); +SPINE_FLUTTER_EXPORT spine_color spine_slot_get_color(spine_slot slot); +SPINE_FLUTTER_EXPORT void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT spine_color spine_slot_get_dark_color(spine_slot slot); +SPINE_FLUTTER_EXPORT void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT int32_t spine_slot_has_dark_color(spine_slot slot); +SPINE_FLUTTER_EXPORT spine_attachment spine_slot_get_attachment(spine_slot slot); +SPINE_FLUTTER_EXPORT void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment); +// OMITTED getDeform() +SPINE_FLUTTER_EXPORT int32_t spine_slot_get_sequence_index(spine_slot slot); +SPINE_FLUTTER_EXPORT void spine_slot_set_sequence_index(spine_slot slot, int32_t sequenceIndex); + +SPINE_FLUTTER_EXPORT int32_t spine_bone_data_get_index(spine_bone_data data); +SPINE_FLUTTER_EXPORT const utf8 *spine_bone_data_get_name(spine_bone_data data); +SPINE_FLUTTER_EXPORT spine_bone_data spine_bone_data_get_parent(spine_bone_data data); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_length(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_length(spine_bone_data data, float length); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_x(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_x(spine_bone_data data, float x); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_y(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_y(spine_bone_data data, float y); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_rotation(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_rotation(spine_bone_data data, float rotation); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_scale_x(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_scale_x(spine_bone_data data, float scaleX); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_scale_y(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_scale_y(spine_bone_data data, float scaleY); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_shear_x(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_shear_x(spine_bone_data data, float shearx); +SPINE_FLUTTER_EXPORT float spine_bone_data_get_shear_y(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_shear_y(spine_bone_data data, float shearY); +SPINE_FLUTTER_EXPORT spine_transform_mode spine_bone_data_get_transform_mode(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_transform_mode(spine_bone_data data, spine_transform_mode mode); +SPINE_FLUTTER_EXPORT int32_t spine_bone_data_is_skin_required(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_is_skin_required(spine_bone_data data, int32_t isSkinRequired); +SPINE_FLUTTER_EXPORT spine_color spine_bone_data_get_color(spine_bone_data data); +SPINE_FLUTTER_EXPORT void spine_bone_data_set_color(spine_bone_data data, float r, float g, float b, float a); + +SPINE_FLUTTER_EXPORT void spine_bone_set_is_y_down(int32_t yDown); +SPINE_FLUTTER_EXPORT int32_t spine_bone_get_is_y_down(); +SPINE_FLUTTER_EXPORT void spine_bone_update(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_update_world_transform(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_update_world_transform_with(spine_bone bone, float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY); +SPINE_FLUTTER_EXPORT void spine_bone_update_applied_transform(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_to_setup_pose(spine_bone bone); +SPINE_FLUTTER_EXPORT spine_vector spine_bone_world_to_local(spine_bone bone, float worldX, float worldY); +SPINE_FLUTTER_EXPORT spine_vector spine_bone_local_to_world(spine_bone bone, float localX, float localY); +SPINE_FLUTTER_EXPORT float spine_bone_world_to_local_rotation(spine_bone bone, float worldRotation); +SPINE_FLUTTER_EXPORT float spine_bone_local_to_world_rotation(spine_bone bone, float localRotation); +SPINE_FLUTTER_EXPORT void spine_bone_rotate_world(spine_bone bone, float degrees); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_to_local_rotation_x(spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_to_local_rotation_y(spine_bone bone); +SPINE_FLUTTER_EXPORT spine_bone_data spine_bone_get_data(spine_bone bone); +SPINE_FLUTTER_EXPORT spine_skeleton spine_bone_get_skeleton(spine_bone bone); +SPINE_FLUTTER_EXPORT spine_bone spine_bone_get_parent(spine_bone bone); +SPINE_FLUTTER_EXPORT int32_t spine_bone_get_num_children(spine_bone bone); +SPINE_FLUTTER_EXPORT spine_bone *spine_bone_get_children(spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_bone_get_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_x(spine_bone bone, float x); +SPINE_FLUTTER_EXPORT float spine_bone_get_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_y(spine_bone bone, float y); +SPINE_FLUTTER_EXPORT float spine_bone_get_rotation(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_rotation(spine_bone bone, float rotation); +SPINE_FLUTTER_EXPORT float spine_bone_get_scale_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_scale_x(spine_bone bone, float scaleX); +SPINE_FLUTTER_EXPORT float spine_bone_get_scale_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_scale_y(spine_bone bone, float scaleY); +SPINE_FLUTTER_EXPORT float spine_bone_get_shear_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_shear_x(spine_bone bone, float shearX); +SPINE_FLUTTER_EXPORT float spine_bone_get_shear_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_shear_y(spine_bone bone, float shearY); +SPINE_FLUTTER_EXPORT float spine_bone_get_applied_rotation(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_applied_rotation(spine_bone bone, float rotation); +SPINE_FLUTTER_EXPORT float spine_bone_get_a_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a_x(spine_bone bone, float x); +SPINE_FLUTTER_EXPORT float spine_bone_get_a_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a_y(spine_bone bone, float y); +SPINE_FLUTTER_EXPORT float spine_bone_get_a_scale_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a_scale_x(spine_bone bone, float scaleX); +SPINE_FLUTTER_EXPORT float spine_bone_get_a_scale_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a_scale_y(spine_bone bone, float scaleY); +SPINE_FLUTTER_EXPORT float spine_bone_get_a_shear_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a_shear_x(spine_bone bone, float shearX); +SPINE_FLUTTER_EXPORT float spine_bone_get_a_shear_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a_shear_y(spine_bone bone, float shearY); +SPINE_FLUTTER_EXPORT float spine_bone_get_a(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_a(spine_bone bone, float a); +SPINE_FLUTTER_EXPORT float spine_bone_get_b(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_b(spine_bone bone, float b); +SPINE_FLUTTER_EXPORT float spine_bone_get_c(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_c(spine_bone bone, float c); +SPINE_FLUTTER_EXPORT float spine_bone_get_d(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_d(spine_bone bone, float d); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_x(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_world_x(spine_bone bone, float worldX); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_y(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_world_y(spine_bone bone, float worldY); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_rotation_x(spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_rotation_y(spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_scale_x(spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_bone_get_world_scale_y(spine_bone bone); +SPINE_FLUTTER_EXPORT int32_t spine_bone_get_is_active(spine_bone bone); +SPINE_FLUTTER_EXPORT void spine_bone_set_is_active(spine_bone bone, int32_t isActive); + +SPINE_FLUTTER_EXPORT const utf8 *spine_attachment_get_name(spine_attachment attachment); +SPINE_FLUTTER_EXPORT spine_attachment_type spine_attachment_get_type(spine_attachment attachment); +SPINE_FLUTTER_EXPORT spine_attachment spine_attachment_copy(spine_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_attachment_dispose(spine_attachment attachment); + +SPINE_FLUTTER_EXPORT spine_vector spine_point_attachment_compute_world_position(spine_point_attachment attachment, spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_point_attachment_compute_world_rotation(spine_point_attachment attachment, spine_bone bone); +SPINE_FLUTTER_EXPORT float spine_point_attachment_get_x(spine_point_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_point_attachment_set_x(spine_point_attachment attachment, float x); +SPINE_FLUTTER_EXPORT float spine_point_attachment_get_y(spine_point_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_point_attachment_set_y(spine_point_attachment attachment, float y); +SPINE_FLUTTER_EXPORT float spine_point_attachment_get_rotation(spine_point_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_point_attachment_set_rotation(spine_point_attachment attachment, float rotation); +SPINE_FLUTTER_EXPORT spine_color spine_point_attachment_get_color(spine_point_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_point_attachment_set_color(spine_point_attachment attachment, float r, float g, float b, float a); + +SPINE_FLUTTER_EXPORT void spine_region_attachment_update_region(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_compute_world_vertices(spine_region_attachment attachment, spine_slot slot, float *worldVertices); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_x(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_x(spine_region_attachment attachment, float x); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_y(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_y(spine_region_attachment attachment, float y); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_rotation(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_rotation(spine_region_attachment attachment, float rotation); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_scale_x(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_scale_x(spine_region_attachment attachment, float scaleX); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_scale_y(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_scale_y(spine_region_attachment attachment, float scaleY); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_width(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_width(spine_region_attachment attachment, float width); +SPINE_FLUTTER_EXPORT float spine_region_attachment_get_height(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_height(spine_region_attachment attachment, float height); +SPINE_FLUTTER_EXPORT spine_color spine_region_attachment_get_color(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_region_attachment_set_color(spine_region_attachment attachment, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT const utf8 *spine_region_attachment_get_path(spine_region_attachment attachment); +// OMITTED setPath() +SPINE_FLUTTER_EXPORT spine_texture_region spine_region_attachment_get_region(spine_region_attachment attachment); +// OMITTED setRegion() +SPINE_FLUTTER_EXPORT spine_sequence spine_region_attachment_get_sequence(spine_region_attachment attachment); +// OMITTED setSequence() +SPINE_FLUTTER_EXPORT int32_t spine_region_attachment_get_num_offset(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT float *spine_region_attachment_get_offset(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t spine_region_attachment_get_num_uvs(spine_region_attachment attachment); +SPINE_FLUTTER_EXPORT float *spine_region_attachment_get_uvs(spine_region_attachment attachment); + +SPINE_FLUTTER_EXPORT int32_t spine_vertex_attachment_get_world_vertices_length(spine_vertex_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_vertex_attachment_compute_world_vertices(spine_vertex_attachment attachment, spine_slot slot, float *worldVertices); +// OMITTED getId() +SPINE_FLUTTER_EXPORT int32_t spine_vertex_attachment_get_num_bones(spine_vertex_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t *spine_vertex_attachment_get_bones(spine_vertex_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t spine_vertex_attachment_get_num_vertices(spine_vertex_attachment attachment); +SPINE_FLUTTER_EXPORT float *spine_vertex_attachment_get_vertices(spine_vertex_attachment attachment); +SPINE_FLUTTER_EXPORT spine_attachment spine_vertex_attachment_get_timeline_attachment(spine_vertex_attachment timelineAttachment); +SPINE_FLUTTER_EXPORT void spine_vertex_attachment_set_timeline_attachment(spine_vertex_attachment attachment, spine_attachment timelineAttachment); +// OMITTED copyTo() + +SPINE_FLUTTER_EXPORT void spine_mesh_attachment_update_region(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t spine_mesh_attachment_get_hull_length(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_mesh_attachment_set_hull_length(spine_mesh_attachment attachment, int32_t hullLength); +SPINE_FLUTTER_EXPORT int32_t spine_mesh_attachment_get_num_region_uvs(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT float *spine_mesh_attachment_get_region_uvs(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t spine_mesh_attachment_get_num_uvs(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT float *spine_mesh_attachment_get_uvs(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t spine_mesh_attachment_get_num_triangles(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT uint16_t *spine_mesh_attachment_get_triangles(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT spine_color spine_mesh_attachment_get_color(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_mesh_attachment_set_color(spine_mesh_attachment attachment, float r, float g, float b, float a); +SPINE_FLUTTER_EXPORT const utf8 *spine_mesh_attachment_get_path(spine_mesh_attachment attachment); +// OMITTED setPath() +SPINE_FLUTTER_EXPORT spine_texture_region spine_mesh_attachment_get_region(spine_mesh_attachment attachment); +// OMITTED setRegion() +SPINE_FLUTTER_EXPORT spine_sequence spine_mesh_attachment_get_sequence(spine_mesh_attachment attachment); +// OMITTED setSequence() +SPINE_FLUTTER_EXPORT spine_mesh_attachment spine_mesh_attachment_get_parent_mesh(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_mesh_attachment_set_parent_mesh(spine_mesh_attachment attachment, spine_mesh_attachment parentMesh); +SPINE_FLUTTER_EXPORT int32_t spine_mesh_attachment_get_num_edges(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT uint16_t *spine_mesh_attachment_get_edges(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT float spine_mesh_attachment_get_width(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_mesh_attachment_set_width(spine_mesh_attachment attachment, float width); +SPINE_FLUTTER_EXPORT float spine_mesh_attachment_get_height(spine_mesh_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_mesh_attachment_set_height(spine_mesh_attachment attachment, float height); +// OMITTED newLinkedMesh() + +SPINE_FLUTTER_EXPORT spine_slot_data spine_clipping_attachment_get_end_slot(spine_clipping_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_clipping_attachment_set_end_slot(spine_clipping_attachment attachment, spine_slot_data endSlot); +SPINE_FLUTTER_EXPORT spine_color spine_clipping_attachment_get_color(spine_clipping_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_clipping_attachment_set_color(spine_clipping_attachment attachment, float r, float g, float b, float a); + +SPINE_FLUTTER_EXPORT spine_color spine_bounding_box_attachment_get_color(spine_bounding_box_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_bounding_box_attachment_set_color(spine_bounding_box_attachment attachment, float r, float g, float b, float a); + +SPINE_FLUTTER_EXPORT int32_t spine_path_attachment_get_num_lengths(spine_path_attachment attachment); +SPINE_FLUTTER_EXPORT float *spine_path_attachment_get_lengths(spine_path_attachment attachment); +SPINE_FLUTTER_EXPORT int32_t spine_path_attachment_get_is_closed(spine_path_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_path_attachment_set_is_closed(spine_path_attachment attachment, int32_t isClosed); +SPINE_FLUTTER_EXPORT int32_t spine_path_attachment_get_is_constant_speed(spine_path_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_path_attachment_set_is_constant_speed(spine_path_attachment attachment, int32_t isConstantSpeed); +SPINE_FLUTTER_EXPORT spine_color spine_path_attachment_get_color(spine_path_attachment attachment); +SPINE_FLUTTER_EXPORT void spine_path_attachment_set_color(spine_path_attachment attachment, float r, float g, float b, float a); + +SPINE_FLUTTER_EXPORT void spine_skin_set_attachment(spine_skin skin, int32_t slotIndex, const utf8 *name, spine_attachment attachment); +SPINE_FLUTTER_EXPORT spine_attachment spine_skin_get_attachment(spine_skin skin, int32_t slotIndex, const utf8 *name); +SPINE_FLUTTER_EXPORT void spine_skin_remove_attachment(spine_skin skin, int32_t slotIndex, const utf8 *name); +// OMITTED findNamesForSlot() +// OMITTED findAttachmentsForSlot() +SPINE_FLUTTER_EXPORT const utf8 *spine_skin_get_name(spine_skin skin); +SPINE_FLUTTER_EXPORT void spine_skin_add_skin(spine_skin skin, spine_skin other); +SPINE_FLUTTER_EXPORT void spine_skin_copy_skin(spine_skin skin, spine_skin other); +SPINE_FLUTTER_EXPORT spine_skin_entries spine_skin_get_entries(spine_skin skin); +SPINE_FLUTTER_EXPORT int32_t spine_skin_entries_get_num_entries(spine_skin_entries entries); +SPINE_FLUTTER_EXPORT spine_skin_entry spine_skin_entries_get_entry(spine_skin_entries entries, int32_t index); +SPINE_FLUTTER_EXPORT void spine_skin_entries_dispose(spine_skin_entries entries); +SPINE_FLUTTER_EXPORT int32_t spine_skin_entry_get_slot_index(spine_skin_entry entry); +SPINE_FLUTTER_EXPORT utf8 *spine_skin_entry_get_name(spine_skin_entry entry); +SPINE_FLUTTER_EXPORT spine_attachment spine_skin_entry_get_attachment(spine_skin_entry entry); +SPINE_FLUTTER_EXPORT int32_t spine_skin_get_num_bones(spine_skin skin); +SPINE_FLUTTER_EXPORT spine_bone_data *spine_skin_get_bones(spine_skin skin); +SPINE_FLUTTER_EXPORT int32_t spine_skin_get_num_constraints(spine_skin skin); +SPINE_FLUTTER_EXPORT spine_constraint_data *spine_skin_get_constraints(spine_skin skin); +SPINE_FLUTTER_EXPORT spine_skin spine_skin_create(const utf8 *name); +SPINE_FLUTTER_EXPORT void spine_skin_dispose(spine_skin skin); + +SPINE_FLUTTER_EXPORT spine_constraint_type spine_constraint_data_get_type(spine_constraint_data data); +SPINE_FLUTTER_EXPORT const utf8 *spine_constraint_data_get_name(spine_constraint_data data); +SPINE_FLUTTER_EXPORT uint64_t spine_constraint_data_get_order(spine_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_constraint_data_set_order(spine_constraint_data data, uint64_t order); +SPINE_FLUTTER_EXPORT int32_t spine_constraint_data_get_is_skin_required(spine_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_constraint_data_set_is_skin_required(spine_constraint_data data, int32_t isSkinRequired); + +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_data_get_num_bones(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT spine_bone_data *spine_ik_constraint_data_get_bones(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT spine_bone_data spine_ik_constraint_data_get_target(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_target(spine_ik_constraint_data data, spine_bone_data target); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_data_get_bend_direction(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_bend_direction(spine_ik_constraint_data data, int32_t bendDirection); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_data_get_compress(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_compress(spine_ik_constraint_data data, int32_t compress); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_data_get_stretch(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_stretch(spine_ik_constraint_data data, int32_t stretch); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_data_get_uniform(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_uniform(spine_ik_constraint_data data, int32_t uniform); +SPINE_FLUTTER_EXPORT float spine_ik_constraint_data_get_mix(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_mix(spine_ik_constraint_data data, float mix); +SPINE_FLUTTER_EXPORT float spine_ik_constraint_data_get_softness(spine_ik_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_data_set_softness(spine_ik_constraint_data data, float softness); + +SPINE_FLUTTER_EXPORT void spine_ik_constraint_update(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_get_order(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT spine_ik_constraint_data spine_ik_constraint_get_data(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_get_num_bones(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT spine_bone *spine_ik_constraint_get_bones(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT spine_bone spine_ik_constraint_get_target(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_target(spine_ik_constraint constraint, spine_bone target); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_get_bend_direction(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_bend_direction(spine_ik_constraint constraint, int32_t bendDirection); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_get_compress(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_compress(spine_ik_constraint constraint, int32_t compress); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_get_stretch(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_stretch(spine_ik_constraint constraint, int32_t stretch); +SPINE_FLUTTER_EXPORT float spine_ik_constraint_get_mix(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_mix(spine_ik_constraint constraint, float mix); +SPINE_FLUTTER_EXPORT float spine_ik_constraint_get_softness(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_softness(spine_ik_constraint constraint, float softness); +SPINE_FLUTTER_EXPORT int32_t spine_ik_constraint_get_is_active(spine_ik_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_ik_constraint_set_is_active(spine_ik_constraint constraint, int32_t isActive); + +SPINE_FLUTTER_EXPORT int32_t spine_transform_constraint_data_get_num_bones(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT spine_bone_data *spine_transform_constraint_data_get_bones(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT spine_bone_data spine_transform_constraint_data_get_target(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_target(spine_transform_constraint_data data, spine_bone_data target); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_mix_rotate(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_mix_rotate(spine_transform_constraint_data data, float mixRotate); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_mix_x(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_mix_x(spine_transform_constraint_data data, float mixX); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_mix_y(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_mix_y(spine_transform_constraint_data data, float mixY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_mix_scale_x(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_mix_scale_x(spine_transform_constraint_data data, float mixScaleX); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_mix_scale_y(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_mix_scale_y(spine_transform_constraint_data data, float mixScaleY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_mix_shear_y(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_mix_shear_y(spine_transform_constraint_data data, float mixShearY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_offset_rotation(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_offset_rotation(spine_transform_constraint_data data, float offsetRotation); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_offset_x(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_offset_x(spine_transform_constraint_data data, float offsetX); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_offset_y(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_offset_y(spine_transform_constraint_data data, float offsetY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_offset_scale_x(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_offset_scale_x(spine_transform_constraint_data data, float offsetScaleX); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_offset_scale_y(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_offset_scale_y(spine_transform_constraint_data data, float offsetScaleY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_data_get_offset_shear_y(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_offset_shear_y(spine_transform_constraint_data data, float offsetShearY); +SPINE_FLUTTER_EXPORT int32_t spine_transform_constraint_data_get_is_relative(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_is_relative(spine_transform_constraint_data data, int32_t isRelative); +SPINE_FLUTTER_EXPORT int32_t spine_transform_constraint_data_get_is_local(spine_transform_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_data_set_is_local(spine_transform_constraint_data data, int32_t isLocal); + +SPINE_FLUTTER_EXPORT void spine_transform_constraint_update(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT int32_t spine_transform_constraint_get_order(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT spine_transform_constraint_data spine_transform_constraint_get_data(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT int32_t spine_transform_constraint_get_num_bones(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT spine_bone *spine_transform_constraint_get_bones(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT spine_bone spine_transform_constraint_get_target(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_target(spine_transform_constraint constraint, spine_bone target); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_mix_rotate(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_mix_rotate(spine_transform_constraint constraint, float mixRotate); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_mix_x(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_mix_x(spine_transform_constraint constraint, float mixX); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_mix_y(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_mix_y(spine_transform_constraint constraint, float mixY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_mix_scale_x(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_mix_scale_x(spine_transform_constraint constraint, float mixScaleX); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_mix_scale_y(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_mix_scale_y(spine_transform_constraint constraint, float mixScaleY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_mix_shear_y(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_mix_shear_y(spine_transform_constraint constraint, float mixShearY); +SPINE_FLUTTER_EXPORT float spine_transform_constraint_get_is_active(spine_transform_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_transform_constraint_set_is_active(spine_transform_constraint constraint, int32_t isActive); + +SPINE_FLUTTER_EXPORT int32_t spine_path_constraint_data_get_num_bones(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT spine_bone_data *spine_path_constraint_data_get_bones(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT spine_slot_data spine_path_constraint_data_get_target(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_target(spine_path_constraint_data data, spine_slot_data target); +SPINE_FLUTTER_EXPORT spine_position_mode spine_path_constraint_data_get_position_mode(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_position_mode(spine_path_constraint_data data, spine_position_mode positionMode); +SPINE_FLUTTER_EXPORT spine_spacing_mode spine_path_constraint_data_get_spacing_mode(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_spacing_mode(spine_path_constraint_data data, spine_spacing_mode spacingMode); +SPINE_FLUTTER_EXPORT spine_rotate_mode spine_path_constraint_data_get_rotate_mode(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_rotate_mode(spine_path_constraint_data data, spine_rotate_mode rotateMode); +SPINE_FLUTTER_EXPORT float spine_path_constraint_data_get_offset_rotation(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_offset_rotation(spine_path_constraint_data data, float offsetRotation); +SPINE_FLUTTER_EXPORT float spine_path_constraint_data_get_position(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_position(spine_path_constraint_data data, float position); +SPINE_FLUTTER_EXPORT float spine_path_constraint_data_get_spacing(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_spacing(spine_path_constraint_data data, float spacing); +SPINE_FLUTTER_EXPORT float spine_path_constraint_data_get_mix_rotate(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_mix_rotate(spine_path_constraint_data data, float mixRotate); +SPINE_FLUTTER_EXPORT float spine_path_constraint_data_get_mix_x(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_mix_x(spine_path_constraint_data data, float mixX); +SPINE_FLUTTER_EXPORT float spine_path_constraint_data_get_mix_y(spine_path_constraint_data data); +SPINE_FLUTTER_EXPORT void spine_path_constraint_data_set_mix_y(spine_path_constraint_data data, float mixY); + +SPINE_FLUTTER_EXPORT void spine_path_constraint_update(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT int32_t spine_path_constraint_get_order(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT spine_path_constraint_data spine_path_constraint_get_data(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT int32_t spine_path_constraint_get_num_bones(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT spine_bone *spine_path_constraint_get_bones(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT spine_slot spine_path_constraint_get_target(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_target(spine_path_constraint constraint, spine_slot target); +SPINE_FLUTTER_EXPORT float spine_path_constraint_get_position(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_position(spine_path_constraint constraint, float position); +SPINE_FLUTTER_EXPORT float spine_path_constraint_get_spacing(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_spacing(spine_path_constraint constraint, float spacing); +SPINE_FLUTTER_EXPORT float spine_path_constraint_get_mix_rotate(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_mix_rotate(spine_path_constraint constraint, float mixRotate); +SPINE_FLUTTER_EXPORT float spine_path_constraint_get_mix_x(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_mix_x(spine_path_constraint constraint, float mixX); +SPINE_FLUTTER_EXPORT float spine_path_constraint_get_mix_y(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_mix_y(spine_path_constraint constraint, float mixY); +SPINE_FLUTTER_EXPORT int32_t spine_path_constraint_get_is_active(spine_path_constraint constraint); +SPINE_FLUTTER_EXPORT void spine_path_constraint_set_is_active(spine_path_constraint constraint, int32_t isActive); + +// OMITTED copy() +SPINE_FLUTTER_EXPORT void spine_sequence_apply(spine_sequence sequence, spine_slot slot, spine_attachment attachment); +SPINE_FLUTTER_EXPORT const utf8 *spine_sequence_get_path(spine_sequence sequence, const utf8 *basePath, int32_t index); +SPINE_FLUTTER_EXPORT int32_t spine_sequence_get_id(spine_sequence sequence); +SPINE_FLUTTER_EXPORT void spine_sequence_set_id(spine_sequence sequence, int32_t id); +SPINE_FLUTTER_EXPORT int32_t spine_sequence_get_start(spine_sequence sequence); +SPINE_FLUTTER_EXPORT void spine_sequence_set_start(spine_sequence sequence, int32_t start); +SPINE_FLUTTER_EXPORT int32_t spine_sequence_get_digits(spine_sequence sequence); +SPINE_FLUTTER_EXPORT void spine_sequence_set_digits(spine_sequence sequence, int32_t digits); +SPINE_FLUTTER_EXPORT int32_t spine_sequence_get_setup_index(spine_sequence sequence); +SPINE_FLUTTER_EXPORT void spine_sequence_set_setup_index(spine_sequence sequence, int32_t setupIndex); +SPINE_FLUTTER_EXPORT int32_t spine_sequence_get_num_regions(spine_sequence sequence); +SPINE_FLUTTER_EXPORT spine_texture_region *spine_sequence_get_regions(spine_sequence sequence); + +SPINE_FLUTTER_EXPORT void *spine_texture_region_get_texture(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_texture(spine_texture_region textureRegion, void *texture); +SPINE_FLUTTER_EXPORT float spine_texture_region_get_u(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_u(spine_texture_region textureRegion, float u); +SPINE_FLUTTER_EXPORT float spine_texture_region_get_v(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_v(spine_texture_region textureRegion, float v); +SPINE_FLUTTER_EXPORT float spine_texture_region_get_u2(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_u2(spine_texture_region textureRegion, float u2); +SPINE_FLUTTER_EXPORT float spine_texture_region_get_v2(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_v2(spine_texture_region textureRegion, float v2); +SPINE_FLUTTER_EXPORT int32_t spine_texture_region_get_degrees(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_degrees(spine_texture_region textureRegion, int32_t degrees); +SPINE_FLUTTER_EXPORT float spine_texture_region_get_offset_x(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_offset_x(spine_texture_region textureRegion, float offsetX); +SPINE_FLUTTER_EXPORT float spine_texture_region_get_offset_y(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_offset_y(spine_texture_region textureRegion, float offsetY); +SPINE_FLUTTER_EXPORT int32_t spine_texture_region_get_width(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_width(spine_texture_region textureRegion, int32_t width); +SPINE_FLUTTER_EXPORT int32_t spine_texture_region_get_height(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_height(spine_texture_region textureRegion, int32_t height); +SPINE_FLUTTER_EXPORT int32_t spine_texture_region_get_original_width(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_original_width(spine_texture_region textureRegion, int32_t originalWidth); +SPINE_FLUTTER_EXPORT int32_t spine_texture_region_get_original_height(spine_texture_region textureRegion); +SPINE_FLUTTER_EXPORT void spine_texture_region_set_original_height(spine_texture_region textureRegion, int32_t originalHeight); + +#endif \ No newline at end of file diff --git a/spine-flutter/windows/.gitignore b/spine-flutter/windows/.gitignore new file mode 100644 index 000000000..b3eb2be16 --- /dev/null +++ b/spine-flutter/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/spine-flutter/windows/CMakeLists.txt b/spine-flutter/windows/CMakeLists.txt new file mode 100644 index 000000000..cd235bb5c --- /dev/null +++ b/spine-flutter/windows/CMakeLists.txt @@ -0,0 +1,23 @@ +# The Flutter tooling requires that developers have a version of Visual Studio +# installed that includes CMake 3.14 or later. You should not increase this +# version, as doing so will cause the plugin to fail to compile for some +# customers of the plugin. +cmake_minimum_required(VERSION 3.14) + +# Project-level configuration. +set(PROJECT_NAME "spine_flutter") +project(${PROJECT_NAME} LANGUAGES CXX) + +# Invoke the build for native code shared with the other target platforms. +# This can be changed to accomodate different builds. +add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared") + +# List of absolute paths to libraries that should be bundled with the plugin. +# This list could contain prebuilt libraries, or libraries created by an +# external build triggered from this build file. +set(spine_flutter_bundled_libraries + # Defined in ../src/CMakeLists.txt. + # This can be changed to accomodate different builds. + $ + PARENT_SCOPE +)