diff --git a/.github/workflows/spine-android.yml b/.github/workflows/spine-android.yml new file mode 100644 index 000000000..bb2826ec7 --- /dev/null +++ b/.github/workflows/spine-android.yml @@ -0,0 +1,35 @@ +name: Build spine-android + +on: + push: + paths: + - 'spine-android/**' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: "17" + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + with: + api-level: 34 + build-tools: 35.0.0 + + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-gradle + + - name: Build spine-android + working-directory: spine-android + run: ./gradlew publishReleasePublicationToSonaType -PossrhUsername=${{ secrets.SONATYPE_USER }} -PossrhPassword=${{ secrets.SONATYPE_PASSWORD }} diff --git a/.github/workflows/spine-godot-v4-all.yml b/.github/workflows/spine-godot-v4-all.yml index 47007e702..cb10cc40a 100644 --- a/.github/workflows/spine-godot-v4-all.yml +++ b/.github/workflows/spine-godot-v4-all.yml @@ -14,8 +14,8 @@ jobs: matrix: version: [ - {"tag": "4.1.4-stable", "version": "4.1.4.stable", "mono": false}, - {"tag": "4.1.4-stable", "version": "4.1.4.stable", "mono": true}, + {"tag": "4.3-stable", "version": "4.3.stable", "mono": false}, + {"tag": "4.3-stable", "version": "4.3.stable", "mono": true}, {"tag": "4.2.2-stable", "version": "4.2.2.stable", "mono": false}, {"tag": "4.2.2-stable", "version": "4.2.2.stable", "mono": true}, ] diff --git a/.github/workflows/spine-godot-v4.yml b/.github/workflows/spine-godot-v4.yml index 4b15f1538..c3b59d159 100644 --- a/.github/workflows/spine-godot-v4.yml +++ b/.github/workflows/spine-godot-v4.yml @@ -34,7 +34,7 @@ env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_EC2_METADATA_DISABLED: true - EM_VERSION: 3.1.18 + EM_VERSION: 3.1.26 GODOT_TAG: ${{ inputs.godot_tag }} GODOT_VERSION: ${{ inputs.godot_version }} GODOT_MONO: ${{ inputs.godot_mono }} @@ -302,6 +302,42 @@ jobs: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} path: spine-godot/godot/bin/web_release.zip + - name: Upload artifacts no threads debug + uses: actions/upload-artifact@v3 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-nothreads-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + path: spine-godot/godot/bin/web_nothreads_debug.zip + + - name: Upload artifacts no threads release + uses: actions/upload-artifact@v3 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-nothreads-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + path: spine-godot/godot/bin/web_nothreads_release.zip + + - name: Upload artifacts dlink debug + uses: actions/upload-artifact@v3 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + path: spine-godot/godot/bin/web_dlink_debug.zip + + - name: Upload artifacts dlink release + uses: actions/upload-artifact@v3 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + path: spine-godot/godot/bin/web_dlink_release.zip + + - name: Upload artifacts dlink nothreads debug + uses: actions/upload-artifact@v3 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-nothreads-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + path: spine-godot/godot/bin/web_dlink_nothreads_debug.zip + + - name: Upload artifacts dlink nothreads release + uses: actions/upload-artifact@v3 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-nothreads-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + path: spine-godot/godot/bin/web_dlink_nothreads_release.zip + upload-to-s3: needs: [godot-editor-windows, godot-editor-linux, godot-editor-macos, godot-template-ios, godot-template-macos, godot-template-windows, godot-template-linux, godot-template-android, godot-template-web] runs-on: ubuntu-latest @@ -309,75 +345,105 @@ jobs: steps: - name: Download godot-editor-windows artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-editor-windows', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-editor-linux artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-editor-linux', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-editor-macos artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-editor-macos', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-ios artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-ios', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-macos artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-macos', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-windows-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-windows-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-windows-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-windows-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-linux-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-linux-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-linux-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-linux-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-android-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-android-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-android-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-android-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-android-source artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-android-source', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-web-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-web-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + - name: Download godot-template-web-nothreads-release artifact + uses: actions/download-artifact@v4 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-nothreads-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + + - name: Download godot-template-web-nothreads-debug artifact + uses: actions/download-artifact@v4 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-nothreads-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + + - name: Download godot-template-web-dlink-release artifact + uses: actions/download-artifact@v4 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + + - name: Download godot-template-web-dlink-debug artifact + uses: actions/download-artifact@v4 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + + - name: Download godot-template-web-dlink-nothreads-release artifact + uses: actions/download-artifact@v4 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-nothreads-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + + - name: Download godot-template-web-dlink-nothreads-debug artifact + uses: actions/download-artifact@v4 + with: + name: ${{ format('{0}-{1}{2}.zip', 'godot-template-web-dlink-nothreads-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} + - name: Upload artifacts to S3 shell: bash if: env.AWS_ACCESS_KEY_ID != null @@ -391,9 +457,24 @@ jobs: aws s3 cp godot-editor-windows.zip s3://spine-godot/$BRANCH/$GODOT_TAG/ aws s3 cp godot-editor-linux.zip s3://spine-godot/$BRANCH/$GODOT_TAG/ aws s3 cp godot-editor-macos.zip s3://spine-godot/$BRANCH/$GODOT_TAG/ + echo "$GODOT_VERSION" > version.txt + # Extract the major and minor version from GODOT_VERSION + GODOT_MAJOR_MINOR=$(echo "$GODOT_VERSION" | sed -E 's/^([0-9]+\.[0-9]+).*/\1/') + + # Check if the version is >= 4.3 + if [[ $(echo "$GODOT_MAJOR_MINOR >= 4.3" | bc) -eq 1 ]]; then + mv web_release.zip web_nothreads_release.zip + mv web_debug.zip web_nothreads_debug.zip + WEB_RELEASE_FILE="web_nothreads_release.zip" + WEB_DEBUG_FILE="web_nothreads_debug.zip" + else + WEB_RELEASE_FILE="web_release.zip" + WEB_DEBUG_FILE="web_debug.zip" + fi + ls -lah - zip spine-godot-templates-$BRANCH-$GODOT_TAG.zip ios.zip macos.zip windows_debug_x86_64.exe windows_release_x86_64.exe linux_debug.x86_64 linux_release.x86_64 web_debug.zip web_release.zip android_release.apk android_debug.apk android_source.zip version.txt + zip spine-godot-templates-$BRANCH-$GODOT_TAG.zip ios.zip macos.zip windows_debug_x86_64.exe windows_release_x86_64.exe linux_debug.x86_64 linux_release.x86_64 "$WEB_DEBUG_FILE" "$WEB_RELEASE_FILE" android_release.apk android_debug.apk android_source.zip version.txt aws s3 cp spine-godot-templates-$BRANCH-$GODOT_TAG.zip s3://spine-godot/$BRANCH/$GODOT_TAG/spine-godot-templates-$BRANCH-$GODOT_TAG.tpz upload-to-s3-mono: @@ -403,42 +484,42 @@ jobs: steps: - name: Download godot-editor-windows artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-editor-windows', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-editor-linux artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-editor-linux', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-editor-macos artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-editor-macos', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-macos artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-macos', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-windows-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-windows-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-windows-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-windows-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-linux-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-linux-release', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} - name: Download godot-template-linux-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: ${{ format('{0}-{1}{2}.zip', 'godot-template-linux-debug', env.GODOT_TAG, env.GODOT_MONO_UPLOAD_SUFFIX) }} diff --git a/.github/workflows/spine-godot.yml b/.github/workflows/spine-godot.yml index a1aff5988..78a304dbc 100644 --- a/.github/workflows/spine-godot.yml +++ b/.github/workflows/spine-godot.yml @@ -12,8 +12,8 @@ env: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_EC2_METADATA_DISABLED: true EM_VERSION: 3.1.14 - GODOT_TAG: 3.5.3-stable - GODOT_VERSION: 3.5.3.stable + GODOT_TAG: 3.6-stable + GODOT_VERSION: 3.6.stable jobs: godot-editor-windows: @@ -33,7 +33,7 @@ jobs: ./spine-godot/build/build.sh release_debug - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-editor-windows.zip path: spine-godot/godot/bin/godot.windows.opt.tools.64.exe @@ -57,7 +57,7 @@ jobs: ./spine-godot/build/build.sh release_debug - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-editor-linux.zip path: spine-godot/godot/bin/godot.x11.opt.tools.64 @@ -82,7 +82,7 @@ jobs: popd - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-editor-macos.zip path: spine-godot/godot/bin/godot-editor-macos.zip @@ -103,7 +103,7 @@ jobs: ./spine-godot/build/build-templates.sh ios - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-ios.zip path: spine-godot/godot/bin/iphone.zip @@ -124,7 +124,7 @@ jobs: ./spine-godot/build/build-templates.sh macos - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-macos.zip path: spine-godot/godot/bin/osx.zip @@ -147,13 +147,13 @@ jobs: ./spine-godot/build/build-templates.sh linux - name: Upload artifacts debug - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-linux-debug.zip path: spine-godot/godot/bin/linux_x11_64_debug - name: Upload artifacts release - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-linux-release.zip path: spine-godot/godot/bin/linux_x11_64_release @@ -175,13 +175,13 @@ jobs: ./spine-godot/build/build-templates.sh windows - name: Upload artifacts debug - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-windows-debug.zip path: spine-godot/godot/bin/windows_64_debug.exe - name: Upload artifacts release - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-windows-release.zip path: spine-godot/godot/bin/windows_64_release.exe @@ -203,7 +203,7 @@ jobs: - name: Set up Java 11 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Setup python and scons uses: ./.github/actions/setup-godot-deps-3 @@ -215,19 +215,19 @@ jobs: ./spine-godot/build/build-templates.sh android - name: Upload artifacts debug - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-android-debug.zip path: spine-godot/godot/bin/android_debug.apk - name: Upload artifacts release - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-android-release.zip path: spine-godot/godot/bin/android_release.apk - name: Upload artifacts source - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-android-source.zip path: spine-godot/godot/bin/android_source.zip @@ -257,13 +257,13 @@ jobs: ./spine-godot/build/build-templates.sh web - name: Upload artifacts debug - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-web-debug.zip path: spine-godot/godot/bin/webassembly_debug.zip - name: Upload artifacts release - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: godot-template-web-release.zip path: spine-godot/godot/bin/webassembly_release.zip @@ -273,72 +273,72 @@ jobs: runs-on: ubuntu-latest steps: - name: Download godot-editor-windows artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-editor-windows.zip - name: Download godot-editor-linux artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-editor-linux.zip - name: Download godot-editor-macos artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-editor-macos.zip - name: Download godot-template-ios artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-ios.zip - name: Download godot-template-macos artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-macos.zip - name: Download godot-template-windows-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-windows-release.zip - name: Download godot-template-windows-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-windows-debug.zip - name: Download godot-template-linux-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-linux-release.zip - name: Download godot-template-linux-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-linux-debug.zip - name: Download godot-template-android-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-android-release.zip - name: Download godot-template-android-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-android-debug.zip - name: Download godot-template-android-source artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-android-source.zip - name: Download godot-template-web-release artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-web-release.zip - name: Download godot-template-web-debug artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: godot-template-web-debug.zip diff --git a/.github/workflows/spine-haxe.yml b/.github/workflows/spine-haxe.yml new file mode 100644 index 000000000..e7fe52755 --- /dev/null +++ b/.github/workflows/spine-haxe.yml @@ -0,0 +1,18 @@ +name: Build spine-haxe + +on: + push: + paths: + - 'spine-haxe/**' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build spine-haxe + working-directory: spine-haxe + env: + HAXE_UPDATE_URL: ${{secrets.HAXE_UPDATE_URL}} + run: ./build.sh \ No newline at end of file diff --git a/.github/workflows/spine-libgdx.yml b/.github/workflows/spine-libgdx.yml index 2cfcda5b9..ae6f71263 100644 --- a/.github/workflows/spine-libgdx.yml +++ b/.github/workflows/spine-libgdx.yml @@ -10,26 +10,20 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Set up JDK 1.8 - uses: actions/setup-java@v3 + - uses: actions/checkout@v2 + - name: Set up JDK 17 + uses: actions/setup-java@v3 with: - distribution: 'zulu' - java-version: "8" - server-id: sonatype-nexus-snapshots - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD + java-version: '17' + distribution: 'temurin' - - name: Cache Maven packages + - name: Cache Gradle packages uses: actions/cache@v3 with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-gradle - name: Build spine-libgdx - working-directory: spine-libgdx/spine-libgdx - run: mvn clean deploy - env: - MAVEN_USERNAME: ${{ secrets.SONATYPE_USER }} - MAVEN_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + working-directory: spine-libgdx + run: ./gradlew publishReleasePublicationToSonaType -PossrhUsername=${{ secrets.SONATYPE_USER }} -PossrhPassword=${{ secrets.SONATYPE_PASSWORD }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dcd9e616..72228bd38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,6 +88,7 @@ - **Breaking**: Starting with Unreal Engine 5.3 imported `.skel`/`.json` and `.atlas` files in the same folder must NOT have a common prefix. E.g. `skeleton.json` and `skeleton.atlas` will not work. Make sure to rename at least one of the two files so there is no prefix collision, e.g. `skeleton-data.json` and `skeleton.atlas`. - Added compatibility with UE 5.3 - Added more example maps +- Added blueprint-callable methods `PhysicsTranslate()`, `PhysicsRotate()` and `ResetPhysicsConstraints()` (which will reset all physics constraints in the skeleton) to `SpineSkeletonComponent` and `SpineWidget`. ### Godot @@ -122,7 +123,7 @@ ### Unity -- **Officially supported Unity versions are 2017.1-2022.1**. +- **Officially supported Unity versions are 2017.1-2023.1**. - **Additions** @@ -160,6 +161,9 @@ - All Spine Outline shaders, including the URP outline shader, now provide an additional parameter `Width in Screen Space`. Enable it to keep the outline width constant in screen space instead of texture space. Requires more expensive computations, so enable only where necessary. Defaults to `disabled` to maintain existing behaviour. - Added support for BlendModeMaterials at runtime instantiation from files via an additional method `SkeletonDataAsset.SetupRuntimeBlendModeMaterials`. See example scene `Spine Examples/Other Examples/Instantiate from Script` for a usage example. - SkeletonGraphic: You can now offset the skeleton mesh relative to the pivot via a newly added green circle handle. This allows you to e.g. frame only the face of a skeleton inside a masked frame. Previously offsetting the pivot downwards fails when `Layout Scale Mode` scales the mesh smaller and towards the pivot (e.g. the feet) and thus out of the frame. Now you can keep the pivot in the center of the `RectTransform` while offsetting only the mesh downwards, keeping the desired skeleton area (e.g. the face) centered while resizing. Moving the new larger green circle handle moves the mesh offset, while moving the blue pivot circle handle moves the pivot as usual. + - `Universal Render Pipeline/Spine/Skeleton` shader now performs proper alpha-testing when `Depth Write` is enabled, using the existing `Shadow alpha cutoff` parameter. + - `SkeletonRootMotion` components now provide a public `Initialize()` method which is automatically called when calling `skeletonAnimation.Initialize(true)` to update the necessary skeleton references. If a different root bone shall be used, be sure to set `skeletonRootMotion.rootMotionBoneName` before calling `skeletonAnimation.Initialize(true)`. + - Skeleton Mecanim: Added new `Mix Mode` `Match`. When selected, Spine animation weights are calculated to best match the provided Mecanim clip weights. This mix mode is recommended on any layer using blend tree nodes. - **Breaking changes** @@ -172,6 +176,9 @@ - Inspector: String attribute `SpineSkin()` now allows to include `` in the list of parameters. Previously the `includeNone=true` parameter of the `SpineSkin()` attribute defaulted to `true` but was ignored. Now it defaults to `false` and has an effect on the list. Only the Inspector GUI is affected by this behaviour change. - `SkeletonGraphicRenderTexture` example component: `protected RawImage quadRawImage` was changed to `protected SkeletonSubmeshGraphic quadMaskableGraphic` for a bugfix. This is only relevant for subclasses of `SkeletonGraphicRenderTexture` or when querying the `RawImage` component via e.g. `skeletonGraphicRenderTexture.quad.GetComponent()`. - Fixed a bug where when Linear color space is used and `PMA vertex colors` enabled, additive slots add a too dark (too transparent) color value. If you want the old incorrect behaviour (darker additive slots) or are not using Linear but Gamma color space, you can comment-out the define `LINEAR_COLOR_SPACE_FIX_ADDITIVE_ALPHA` in `MeshGenerator.cs` to deactivate the fix or just to skip unnecessary instructions. + - Fixed SkeletonRootMotion components ignoring parent bone scale when set by transform constraints. Using applied scale of parent bone now. If you need the old behaviour, comment out the line `#define USE_APPLIED_PARENT_SCALE` in SkeletonRootMotionBase.cs. + - Fixed SkeletonUtility callback update order when used with SkeletonRootMotion components so that the position when following a bone is updated after SkeletonRootMotion clears root-bone position. The order of SkeletonUtilityBone callbacks is changed to be later to achieve this. This is a breaking change in the unlikely case that you are using SkeletonRootMotion together with SkeletonUtility and subscribed to `UpdateLocal`, `UpdateWorld` or `UpdateComplete` yourself and relied on a certain callback order. One solution is to then resubscribe your own callback events accordingly by calling + `.UpdateLocal -= Callback; .UpdateLocal += Callback;`. - **Changes of default values** @@ -337,6 +344,7 @@ - `VertexEffect` has been removed. ### Cocos2d-x +- Renamed `SkeletonRenderer` to `SkeletonRendererCocos2dX` to avoid name clash with spine-cpp class. ### SFML @@ -421,6 +429,7 @@ - Made `SkeletonGraphic.unscaledTime` parameter protected, use the new property `UnscaledTime` instead. - `SkeletonGraphic` `OnRebuild` callback delegate is now issued after the skeleton has been initialized, before the `AnimationState` component is initialized. This makes behaviour consistent with `SkeletonAnimation` and `SkeletonMecanim` component behaviour. Use the new callback `OnAnimationRebuild` if you want to receive a callback after the `SkeletonGraphic` `AnimationState` has been initialized. + - Changed name of prefab skeleton meshes stored at prefabs from `Skeleton Prefab Mesh "name"` to `Skeleton Prefab Mesh [name]` to avoid issues with quotes in mesh asset names (see [this issue](https://github.com/EsotericSoftware/spine-runtimes/issues/2572)). Likely this change poses no problems at all, however if you are parsing the prefab's mesh name for whatever reason, be sure to adjust the pattern accordingly. - **Changes of default values** diff --git a/examples/export/runtimes.sh b/examples/export/runtimes.sh index 9d1856d8c..7c7e48532 100755 --- a/examples/export/runtimes.sh +++ b/examples/export/runtimes.sh @@ -35,6 +35,29 @@ cp -f ../mix-and-match/export/*.json "$ROOT/spine-libgdx/spine-libgdx-tests/asse cp -f ../mix-and-match/export/*.skel "$ROOT/spine-libgdx/spine-libgdx-tests/assets/mix-and-match/" cp -f ../mix-and-match/export/*-pma.* "$ROOT/spine-libgdx/spine-libgdx-tests/assets/mix-and-match/" +echo "spine-android" +rm "$ROOT/spine-android/app/src/main/assets/"* +cp -f ../celestial-circus/export/celestial-circus-pro.skel "$ROOT/spine-android/app/src/main/assets/" +cp -f ../celestial-circus/export/celestial-circus.atlas "$ROOT/spine-android/app/src/main/assets" +cp -f ../celestial-circus/export/celestial-circus.png "$ROOT/spine-android/app/src/main/assets" + +cp -f ../dragon/export/dragon-ess.skel "$ROOT/spine-android/app/src/main/assets/" +cp -f ../dragon/export/dragon.atlas "$ROOT/spine-android/app/src/main/assets" +cp -f ../dragon/export/dragon.png "$ROOT/spine-android/app/src/main/assets" +cp -f ../dragon/export/dragon_2.png "$ROOT/spine-android/app/src/main/assets" +cp -f ../dragon/export/dragon_3.png "$ROOT/spine-android/app/src/main/assets" +cp -f ../dragon/export/dragon_4.png "$ROOT/spine-android/app/src/main/assets" +cp -f ../dragon/export/dragon_5.png "$ROOT/spine-android/app/src/main/assets" + +cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-android/app/src/main/assets/" +cp -f ../mix-and-match/export/mix-and-match.atlas "$ROOT/spine-android/app/src/main/assets/" +cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-android/app/src/main/assets/" + +cp -f ../spineboy/export/spineboy-pro.skel "$ROOT/spine-android/app/src/main/assets/" +cp -f ../spineboy/export/spineboy-pro.json "$ROOT/spine-android/app/src/main/assets/" +cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-android/app/src/main/assets/" +cp -f ../spineboy/export/spineboy.png "$ROOT/spine-android/app/src/main/assets/" + rm -f "$ROOT/spine-libgdx/spine-libgdx-tests/assets/sack/"* mkdir -p "$ROOT/spine-libgdx/spine-libgdx-tests/assets/sack/" cp -f ../sack/export/sack-pro.json "$ROOT/spine-libgdx/spine-libgdx-tests/assets/sack/" @@ -453,6 +476,19 @@ cp -f ../spineboy/export/spineboy-ess.json "$ROOT/spine-ts/spine-canvas/example/ cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-ts/spine-canvas/example/assets/" cp -f ../spineboy/export/spineboy.png "$ROOT/spine-ts/spine-canvas/example/assets/" +rm "$ROOT/spine-ts/spine-canvaskit/example/assets/"* +cp -f ../spineboy/export/spineboy-pro.skel "$ROOT/spine-ts/spine-canvaskit/example/assets/" +cp -f ../spineboy/export/spineboy.atlas "$ROOT/spine-ts/spine-canvaskit/example/assets/" +cp -f ../spineboy/export/spineboy.png "$ROOT/spine-ts/spine-canvaskit/example/assets/" + +cp -f ../mix-and-match/export/mix-and-match-pro.skel "$ROOT/spine-ts/spine-canvaskit/example/assets/" +cp -f ../mix-and-match/export/mix-and-match.atlas "$ROOT/spine-ts/spine-canvaskit/example/assets/" +cp -f ../mix-and-match/export/mix-and-match.png "$ROOT/spine-ts/spine-canvaskit/example/assets/" + +cp -f ../celestial-circus/export/celestial-circus-pro.json "$ROOT/spine-ts/spine-canvaskit/example/assets/" +cp -f ../celestial-circus/export/celestial-circus.atlas "$ROOT/spine-ts/spine-canvaskit/example/assets/" +cp -f ../celestial-circus/export/celestial-circus.png "$ROOT/spine-ts/spine-canvaskit/example/assets/" + rm "$ROOT/spine-ts/spine-threejs/example/assets/"* cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-ts/spine-threejs/example/assets/" cp -f ../raptor/export/raptor.atlas "$ROOT/spine-ts/spine-threejs/example/assets/" diff --git a/formatters/build.gradle b/formatters/build.gradle index 2886d7a77..1b8b485ae 100644 --- a/formatters/build.gradle +++ b/formatters/build.gradle @@ -8,7 +8,8 @@ spotless { lineEndings 'UNIX' java { - target 'spine-libgdx/**/*.java' + target 'spine-libgdx/**/*.java', + 'spine-android/**/*.java' eclipse().configFile('formatters/eclipse-formatter.xml') } diff --git a/spine-android/.gitignore b/spine-android/.gitignore new file mode 100644 index 000000000..aa724b770 --- /dev/null +++ b/spine-android/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/spine-android/app/.gitignore b/spine-android/app/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/spine-android/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/spine-android/app/build.gradle.kts b/spine-android/app/build.gradle.kts new file mode 100644 index 000000000..04d6b5962 --- /dev/null +++ b/spine-android/app/build.gradle.kts @@ -0,0 +1,75 @@ +plugins { + alias(libs.plugins.androidApplication) + alias(libs.plugins.jetbrainsKotlinAndroid) +} + +android { + namespace = "com.esotericsoftware.spine" + compileSdk = 34 + + defaultConfig { + applicationId = "com.esotericsoftware.spine" + minSdk = 23 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.5.1" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.navigation.compose) + implementation(libs.appcompat) + + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) + + implementation(project(":spine-android")) + // implementation("com.esotericsoftware.spine:spine-android:4.2.2-SNAPSHOT") +} diff --git a/spine-android/app/proguard-rules.pro b/spine-android/app/proguard-rules.pro new file mode 100644 index 000000000..481bb4348 --- /dev/null +++ b/spine-android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/spine-android/app/src/androidTest/java/com/esotericsoftware/android/ExampleInstrumentedTest.kt b/spine-android/app/src/androidTest/java/com/esotericsoftware/android/ExampleInstrumentedTest.kt new file mode 100644 index 000000000..efa76c79c --- /dev/null +++ b/spine-android/app/src/androidTest/java/com/esotericsoftware/android/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.esotericsoftware.android + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.esotericsoftware.spine", appContext.packageName) + } +} \ No newline at end of file diff --git a/spine-android/app/src/main/AndroidManifest.xml b/spine-android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..35fd26c4b --- /dev/null +++ b/spine-android/app/src/main/AndroidManifest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/spine-android/app/src/main/assets/celestial-circus-pro.skel b/spine-android/app/src/main/assets/celestial-circus-pro.skel new file mode 100644 index 000000000..cf834001b Binary files /dev/null and b/spine-android/app/src/main/assets/celestial-circus-pro.skel differ diff --git a/spine-android/app/src/main/assets/celestial-circus.atlas b/spine-android/app/src/main/assets/celestial-circus.atlas new file mode 100644 index 000000000..17f32b2a3 --- /dev/null +++ b/spine-android/app/src/main/assets/celestial-circus.atlas @@ -0,0 +1,173 @@ +celestial-circus.png + size: 1024, 1024 + filter: Linear, Linear + scale: 0.4 +arm-back-down + bounds: 324, 401, 38, 82 + rotate: 90 +arm-back-up + bounds: 290, 44, 83, 116 + rotate: 90 +arm-front-down + bounds: 706, 2, 36, 78 + rotate: 90 +arm-front-up + bounds: 860, 138, 77, 116 +bench + bounds: 725, 256, 189, 48 +body-bottom + bounds: 879, 868, 154, 124 + rotate: 90 +body-top + bounds: 725, 128, 126, 133 + rotate: 90 +chest + bounds: 408, 26, 104, 93 +cloud-back + bounds: 752, 378, 202, 165 +cloud-front + bounds: 2, 2, 325, 196 + rotate: 90 +collar + bounds: 786, 13, 47, 26 +ear + bounds: 1002, 643, 20, 28 +eye-back-shadow + bounds: 428, 395, 14, 10 +eye-front-shadow + bounds: 704, 529, 24, 14 +eye-reflex-back + bounds: 860, 128, 8, 7 + rotate: 90 +eye-reflex-front + bounds: 726, 386, 10, 7 +eye-white-back + bounds: 835, 23, 13, 16 +eye-white-front + bounds: 1005, 1000, 22, 17 + rotate: 90 +eyelashes-down-back + bounds: 232, 329, 11, 6 + rotate: 90 +eyelashes-down-front + bounds: 913, 851, 15, 6 + rotate: 90 +eyelashes-top-back + bounds: 408, 395, 18, 10 +eyelashes-top-front + bounds: 702, 179, 30, 16 + rotate: 90 +face + bounds: 514, 26, 93, 102 + rotate: 90 +feathers-back + bounds: 954, 625, 46, 46 +feathers-front + bounds: 706, 40, 72, 86 +fringe-middle-back + bounds: 200, 6, 33, 52 + rotate: 90 +fringe-middle-front + bounds: 878, 76, 60, 50 + rotate: 90 +fringe-side-back + bounds: 780, 41, 27, 94 + rotate: 90 +fringe-side-front + bounds: 939, 161, 26, 93 +glove-bottom-back + bounds: 954, 572, 51, 41 + rotate: 90 +glove-bottom-front + bounds: 916, 256, 47, 48 +hair-back-1 + bounds: 444, 395, 132, 306 + rotate: 90 +hair-back-2 + bounds: 438, 211, 80, 285 + rotate: 90 +hair-back-3 + bounds: 719, 306, 70, 268 + rotate: 90 +hair-back-4 + bounds: 438, 121, 88, 262 + rotate: 90 +hair-back-5 + bounds: 438, 293, 88, 279 + rotate: 90 +hair-back-6 + bounds: 200, 41, 88, 286 +hair-hat-shadow + bounds: 232, 398, 90, 41 +hand-back + bounds: 954, 673, 60, 47 + rotate: 90 +hand-front + bounds: 967, 172, 53, 60 +hat-back + bounds: 954, 802, 64, 45 + rotate: 90 +hat-front + bounds: 780, 70, 96, 56 +head-back + bounds: 618, 17, 102, 86 + rotate: 90 +jabot + bounds: 967, 234, 70, 55 + rotate: 90 +leg-back + bounds: 232, 441, 210, 333 +leg-front + bounds: 444, 529, 258, 320 +logo-brooch + bounds: 954, 545, 16, 25 +mouth + bounds: 408, 121, 22, 6 +neck + bounds: 232, 342, 39, 56 + rotate: 90 +nose + bounds: 742, 529, 6, 7 + rotate: 90 +nose-highlight + bounds: 719, 300, 4, 4 +nose-shadow + bounds: 869, 128, 7, 8 +pupil-back + bounds: 730, 529, 10, 14 +pupil-front + bounds: 254, 21, 12, 18 +rope-back + bounds: 232, 383, 10, 492 + rotate: 90 +rope-front + bounds: 232, 383, 10, 492 + rotate: 90 +rope-front-bottom + bounds: 954, 735, 42, 65 +skirt + bounds: 2, 776, 440, 246 +sock-bow + bounds: 408, 407, 33, 32 +spine-logo-body + bounds: 879, 853, 13, 32 + rotate: 90 +star-big + bounds: 939, 141, 18, 24 + rotate: 90 +star-medium + bounds: 742, 537, 6, 8 + rotate: 90 +star-small + bounds: 719, 378, 3, 4 + rotate: 90 +underskirt + bounds: 2, 329, 445, 228 + rotate: 90 +underskirt-back + bounds: 444, 851, 433, 171 +wing-back + bounds: 290, 129, 146, 252 +wing-front + bounds: 704, 545, 304, 248 + rotate: 90 diff --git a/spine-android/app/src/main/assets/celestial-circus.png b/spine-android/app/src/main/assets/celestial-circus.png new file mode 100644 index 000000000..a5c26ccf2 Binary files /dev/null and b/spine-android/app/src/main/assets/celestial-circus.png differ diff --git a/spine-android/app/src/main/assets/dragon-ess.skel b/spine-android/app/src/main/assets/dragon-ess.skel new file mode 100644 index 000000000..168a2f3c7 Binary files /dev/null and b/spine-android/app/src/main/assets/dragon-ess.skel differ diff --git a/spine-android/app/src/main/assets/dragon.atlas b/spine-android/app/src/main/assets/dragon.atlas new file mode 100644 index 000000000..47b3f3b2a --- /dev/null +++ b/spine-android/app/src/main/assets/dragon.atlas @@ -0,0 +1,112 @@ +dragon.png + size: 1024, 1024 + filter: Linear, Linear +front-toe-a + bounds: 797, 381, 29, 50 +front-toe-b + bounds: 942, 118, 56, 57 +head + bounds: 647, 81, 296, 260 + rotate: 90 +left-front-leg + bounds: 942, 250, 84, 57 + rotate: 90 +left-front-thigh + bounds: 852, 7, 84, 72 +left-wing01 + bounds: 736, 433, 264, 589 +right-rear-toe + bounds: 647, 2, 109, 77 +right-wing01 + bounds: 2, 379, 365, 643 +right-wing02 + bounds: 369, 379, 365, 643 +right-wing03 + bounds: 2, 12, 365, 643 + rotate: 90 +tail03 + bounds: 758, 6, 73, 92 + rotate: 90 +tail04 + bounds: 942, 177, 56, 71 +tail05 + bounds: 736, 379, 52, 59 + rotate: 90 +tail06 + bounds: 942, 336, 95, 68 + rotate: 90 +thiagobrayner + bounds: 909, 81, 350, 31 + rotate: 90 + +dragon_2.png + size: 1024, 1024 + filter: Linear, Linear +back + bounds: 795, 32, 190, 185 +chin + bounds: 647, 157, 214, 146 + rotate: 90 +left-rear-leg + bounds: 795, 219, 206, 177 + rotate: 90 +left-wing02 + bounds: 736, 427, 264, 589 +right-wing04 + bounds: 2, 373, 365, 643 +right-wing05 + bounds: 369, 373, 365, 643 +right-wing06 + bounds: 2, 6, 365, 643 + rotate: 90 +tail01 + bounds: 647, 2, 120, 153 + +dragon_3.png + size: 1024, 1024 + filter: Linear, Linear +chest + bounds: 740, 299, 136, 122 +left-rear-thigh + bounds: 647, 218, 91, 149 +left-wing03 + bounds: 736, 423, 264, 589 +right-front-leg + bounds: 850, 196, 101, 89 + rotate: 90 +right-front-thigh + bounds: 740, 189, 108, 108 +right-rear-leg + bounds: 878, 321, 116, 100 +right-rear-thigh + bounds: 647, 67, 91, 149 +right-wing07 + bounds: 2, 369, 365, 643 +right-wing08 + bounds: 369, 369, 365, 643 +right-wing09 + bounds: 2, 2, 365, 643 + rotate: 90 +tail02 + bounds: 740, 67, 95, 120 + +dragon_4.png + size: 1024, 1024 + filter: Linear, Linear +left-wing04 + bounds: 2, 268, 264, 589 +left-wing05 + bounds: 268, 268, 264, 589 +left-wing06 + bounds: 534, 268, 264, 589 +left-wing07 + bounds: 2, 2, 264, 589 + rotate: 90 + +dragon_5.png + size: 1024, 1024 + filter: Linear, Linear +left-wing08 + bounds: 2, 2, 264, 589 +left-wing09 + bounds: 268, 2, 264, 589 diff --git a/spine-android/app/src/main/assets/dragon.png b/spine-android/app/src/main/assets/dragon.png new file mode 100644 index 000000000..3bca338cd Binary files /dev/null and b/spine-android/app/src/main/assets/dragon.png differ diff --git a/spine-android/app/src/main/assets/dragon_2.png b/spine-android/app/src/main/assets/dragon_2.png new file mode 100644 index 000000000..3dbe2a5a0 Binary files /dev/null and b/spine-android/app/src/main/assets/dragon_2.png differ diff --git a/spine-android/app/src/main/assets/dragon_3.png b/spine-android/app/src/main/assets/dragon_3.png new file mode 100644 index 000000000..df2896d51 Binary files /dev/null and b/spine-android/app/src/main/assets/dragon_3.png differ diff --git a/spine-android/app/src/main/assets/dragon_4.png b/spine-android/app/src/main/assets/dragon_4.png new file mode 100644 index 000000000..270b0959d Binary files /dev/null and b/spine-android/app/src/main/assets/dragon_4.png differ diff --git a/spine-android/app/src/main/assets/dragon_5.png b/spine-android/app/src/main/assets/dragon_5.png new file mode 100644 index 000000000..4e9f7a843 Binary files /dev/null and b/spine-android/app/src/main/assets/dragon_5.png differ diff --git a/spine-android/app/src/main/assets/mix-and-match-pro.skel b/spine-android/app/src/main/assets/mix-and-match-pro.skel new file mode 100644 index 000000000..afe6d4738 Binary files /dev/null and b/spine-android/app/src/main/assets/mix-and-match-pro.skel differ diff --git a/spine-android/app/src/main/assets/mix-and-match.atlas b/spine-android/app/src/main/assets/mix-and-match.atlas new file mode 100644 index 000000000..b8047722c --- /dev/null +++ b/spine-android/app/src/main/assets/mix-and-match.atlas @@ -0,0 +1,358 @@ +mix-and-match.png + size: 1024, 512 + filter: Linear, Linear + scale: 0.5 +base-head + bounds: 118, 70, 95, 73 +boy/arm-front + bounds: 831, 311, 36, 115 + rotate: 90 +boy/backpack + bounds: 249, 357, 119, 153 +boy/backpack-pocket + bounds: 628, 193, 34, 62 + rotate: 90 +boy/backpack-strap-front + bounds: 330, 263, 38, 88 + rotate: 90 +boy/backpack-up + bounds: 482, 171, 21, 70 +boy/body + bounds: 845, 413, 97, 132 + rotate: 90 +boy/boot-ribbon-front + bounds: 234, 304, 9, 11 +boy/collar + bounds: 471, 243, 73, 29 + rotate: 90 +boy/ear + bounds: 991, 352, 19, 23 + rotate: 90 +boy/eye-back-low-eyelid + bounds: 66, 72, 17, 6 +boy/eye-back-pupil + bounds: 694, 279, 8, 9 + rotate: 90 +boy/eye-back-up-eyelid + bounds: 460, 101, 23, 5 + rotate: 90 +boy/eye-back-up-eyelid-back + bounds: 979, 414, 19, 10 + rotate: 90 +boy/eye-front-low-eyelid + bounds: 1015, 203, 22, 7 + rotate: 90 +boy/eye-front-pupil + bounds: 309, 50, 9, 9 +boy/eye-front-up-eyelid + bounds: 991, 373, 31, 6 +boy/eye-front-up-eyelid-back + bounds: 107, 76, 26, 9 + rotate: 90 +boy/eye-iris-back + bounds: 810, 260, 17, 17 +boy/eye-iris-front + bounds: 902, 230, 18, 18 +boy/eye-white-back + bounds: 599, 179, 20, 12 +boy/eye-white-front + bounds: 544, 183, 27, 13 +boy/eyebrow-back + bounds: 1002, 225, 20, 11 + rotate: 90 +boy/eyebrow-front + bounds: 975, 234, 25, 11 +boy/hair-back + bounds: 629, 289, 122, 81 + rotate: 90 +boy/hair-bangs + bounds: 505, 180, 70, 37 + rotate: 90 +boy/hair-side + bounds: 979, 435, 25, 43 + rotate: 90 +boy/hand-backfingers + bounds: 858, 183, 19, 21 +boy/hand-front-fingers + bounds: 879, 183, 19, 21 +boy/hat + bounds: 218, 121, 93, 56 +boy/leg-front + bounds: 85, 104, 31, 158 +boy/mouth-close + bounds: 467, 100, 21, 5 +girl-blue-cape/mouth-close + bounds: 467, 100, 21, 5 +girl-spring-dress/mouth-close + bounds: 467, 100, 21, 5 +girl/mouth-close + bounds: 467, 100, 21, 5 +boy/mouth-smile + bounds: 1015, 258, 29, 7 + rotate: 90 +boy/nose + bounds: 323, 79, 17, 10 +boy/pompom + bounds: 979, 462, 48, 43 + rotate: 90 +boy/zip + bounds: 922, 231, 14, 23 + rotate: 90 +girl-blue-cape/back-eyebrow + bounds: 527, 106, 18, 12 + rotate: 90 +girl-blue-cape/body-dress + bounds: 2, 264, 109, 246 +girl-blue-cape/body-ribbon + bounds: 576, 193, 50, 38 +girl-blue-cape/cape-back + bounds: 113, 317, 134, 193 +girl-blue-cape/cape-back-up + bounds: 504, 305, 123, 106 +girl-blue-cape/cape-ribbon + bounds: 396, 118, 50, 18 + rotate: 90 +girl-blue-cape/cape-shoulder-back + bounds: 420, 243, 49, 59 +girl-blue-cape/cape-shoulder-front + bounds: 2, 2, 62, 76 +girl-blue-cape/cape-up-front + bounds: 118, 145, 98, 117 +girl-blue-cape/ear + bounds: 837, 181, 19, 23 +girl-spring-dress/ear + bounds: 837, 181, 19, 23 +girl/ear + bounds: 837, 181, 19, 23 +girl-blue-cape/eye-back-low-eyelid + bounds: 810, 252, 17, 6 +girl-spring-dress/eye-back-low-eyelid + bounds: 810, 252, 17, 6 +girl/eye-back-low-eyelid + bounds: 810, 252, 17, 6 +girl-blue-cape/eye-back-pupil + bounds: 309, 40, 8, 9 + rotate: 90 +girl-spring-dress/eye-back-pupil + bounds: 309, 40, 8, 9 + rotate: 90 +girl/eye-back-pupil + bounds: 309, 40, 8, 9 + rotate: 90 +girl-blue-cape/eye-back-up-eyelid + bounds: 573, 179, 24, 12 +girl-spring-dress/eye-back-up-eyelid + bounds: 573, 179, 24, 12 +girl/eye-back-up-eyelid + bounds: 573, 179, 24, 12 +girl-blue-cape/eye-back-up-eyelid-back + bounds: 380, 105, 17, 11 + rotate: 90 +girl-spring-dress/eye-back-up-eyelid-back + bounds: 380, 105, 17, 11 + rotate: 90 +girl/eye-back-up-eyelid-back + bounds: 380, 105, 17, 11 + rotate: 90 +girl-blue-cape/eye-front-low-eyelid + bounds: 1016, 353, 18, 6 + rotate: 90 +girl-spring-dress/eye-front-low-eyelid + bounds: 1016, 353, 18, 6 + rotate: 90 +girl/eye-front-low-eyelid + bounds: 1016, 353, 18, 6 + rotate: 90 +girl-blue-cape/eye-front-pupil + bounds: 363, 94, 9, 9 +girl-spring-dress/eye-front-pupil + bounds: 363, 94, 9, 9 +girl/eye-front-pupil + bounds: 363, 94, 9, 9 +girl-blue-cape/eye-front-up-eyelid + bounds: 679, 413, 30, 14 + rotate: 90 +girl-spring-dress/eye-front-up-eyelid + bounds: 679, 413, 30, 14 + rotate: 90 +girl/eye-front-up-eyelid + bounds: 679, 413, 30, 14 + rotate: 90 +girl-blue-cape/eye-front-up-eyelid-back + bounds: 947, 234, 26, 11 +girl-spring-dress/eye-front-up-eyelid-back + bounds: 947, 234, 26, 11 +girl/eye-front-up-eyelid-back + bounds: 947, 234, 26, 11 +girl-blue-cape/eye-iris-back + bounds: 323, 105, 17, 17 +girl-blue-cape/eye-iris-front + bounds: 467, 107, 18, 18 +girl-blue-cape/eye-white-back + bounds: 621, 175, 20, 16 +girl-spring-dress/eye-white-back + bounds: 621, 175, 20, 16 +girl-blue-cape/eye-white-front + bounds: 643, 175, 20, 16 +girl-spring-dress/eye-white-front + bounds: 643, 175, 20, 16 +girl/eye-white-front + bounds: 643, 175, 20, 16 +girl-blue-cape/front-eyebrow + bounds: 309, 101, 18, 12 + rotate: 90 +girl-blue-cape/hair-back + bounds: 712, 317, 117, 98 +girl-blue-cape/hair-bangs + bounds: 313, 170, 91, 40 + rotate: 90 +girl-blue-cape/hair-head-side-back + bounds: 544, 198, 30, 52 +girl-blue-cape/hair-head-side-front + bounds: 466, 127, 41, 42 +girl-blue-cape/hair-side + bounds: 175, 2, 36, 71 + rotate: 90 +girl-blue-cape/hand-front-fingers + bounds: 902, 207, 19, 21 +girl-spring-dress/hand-front-fingers + bounds: 902, 207, 19, 21 +girl-blue-cape/leg-front + bounds: 519, 413, 30, 158 + rotate: 90 +girl-blue-cape/mouth-smile + bounds: 1015, 227, 29, 7 + rotate: 90 +girl-spring-dress/mouth-smile + bounds: 1015, 227, 29, 7 + rotate: 90 +girl/mouth-smile + bounds: 1015, 227, 29, 7 + rotate: 90 +girl-blue-cape/nose + bounds: 342, 82, 11, 7 +girl-spring-dress/nose + bounds: 342, 82, 11, 7 +girl/nose + bounds: 342, 82, 11, 7 +girl-blue-cape/sleeve-back + bounds: 416, 95, 42, 29 +girl-blue-cape/sleeve-front + bounds: 249, 303, 52, 119 + rotate: 90 +girl-spring-dress/arm-front + bounds: 829, 292, 17, 111 + rotate: 90 +girl-spring-dress/back-eyebrow + bounds: 309, 81, 18, 12 + rotate: 90 +girl-spring-dress/body-up + bounds: 66, 2, 64, 66 +girl-spring-dress/cloak-down + bounds: 758, 227, 50, 50 +girl-spring-dress/cloak-up + bounds: 628, 229, 64, 58 +girl-spring-dress/eye-iris-back + bounds: 342, 105, 17, 17 +girl-spring-dress/eye-iris-front + bounds: 487, 107, 18, 18 +girl-spring-dress/front-eyebrow + bounds: 323, 91, 18, 12 +girl-spring-dress/hair-back + bounds: 370, 417, 147, 93 +girl-spring-dress/hair-bangs + bounds: 829, 250, 91, 40 +girl-spring-dress/hair-head-side-back + bounds: 509, 126, 30, 52 +girl-spring-dress/hair-head-side-front + bounds: 816, 206, 41, 42 +girl-spring-dress/hair-side + bounds: 248, 2, 36, 71 + rotate: 90 +girl-spring-dress/leg-front + bounds: 831, 381, 30, 158 + rotate: 90 +girl-spring-dress/neck + bounds: 85, 70, 20, 32 +girl-spring-dress/shoulder-ribbon + bounds: 175, 44, 36, 24 +girl-spring-dress/skirt + bounds: 2, 80, 182, 81 + rotate: 90 +girl-spring-dress/underskirt + bounds: 519, 445, 175, 65 +girl/arm-front + bounds: 712, 279, 36, 115 + rotate: 90 +girl/back-eyebrow + bounds: 309, 61, 18, 12 + rotate: 90 +girl/bag-base + bounds: 694, 219, 62, 58 +girl/bag-strap-front + bounds: 370, 304, 12, 96 + rotate: 90 +girl/bag-top + bounds: 765, 175, 49, 50 +girl/body + bounds: 370, 318, 97, 132 + rotate: 90 +girl/boot-ribbon-front + bounds: 323, 64, 13, 13 +girl/eye-iris-back + bounds: 361, 105, 17, 17 +girl/eye-iris-front + bounds: 507, 106, 18, 18 +girl/eye-white-back + bounds: 665, 175, 20, 16 +girl/front-eyebrow + bounds: 343, 91, 18, 12 +girl/hair-back + bounds: 696, 417, 147, 93 +girl/hair-bangs + bounds: 922, 247, 91, 40 +girl/hair-flap-down-front + bounds: 415, 171, 70, 65 + rotate: 90 +girl/hair-head-side-back + bounds: 991, 381, 30, 52 +girl/hair-head-side-front + bounds: 859, 206, 41, 42 +girl/hair-patch + bounds: 132, 2, 66, 41 + rotate: 90 +girl/hair-side + bounds: 692, 181, 36, 71 + rotate: 90 +girl/hair-strand-back-1 + bounds: 948, 289, 58, 74 + rotate: 90 +girl/hair-strand-back-2 + bounds: 355, 170, 91, 58 + rotate: 90 +girl/hair-strand-back-3 + bounds: 215, 40, 92, 79 +girl/hair-strand-front-1 + bounds: 234, 263, 38, 94 + rotate: 90 +girl/hair-strand-front-2 + bounds: 576, 233, 70, 50 + rotate: 90 +girl/hair-strand-front-3 + bounds: 313, 124, 44, 81 + rotate: 90 +girl/hand-front-fingers + bounds: 923, 208, 19, 21 +girl/hat + bounds: 218, 179, 93, 82 +girl/leg-front + bounds: 831, 349, 30, 158 + rotate: 90 +girl/pompom + bounds: 416, 126, 48, 43 +girl/scarf + bounds: 113, 264, 119, 51 +girl/scarf-back + bounds: 502, 252, 72, 51 +girl/zip + bounds: 816, 179, 19, 25 diff --git a/spine-android/app/src/main/assets/mix-and-match.png b/spine-android/app/src/main/assets/mix-and-match.png new file mode 100644 index 000000000..634a1e230 Binary files /dev/null and b/spine-android/app/src/main/assets/mix-and-match.png differ diff --git a/spine-android/app/src/main/assets/spineboy-pro.json b/spine-android/app/src/main/assets/spineboy-pro.json new file mode 100644 index 000000000..f3ba20944 --- /dev/null +++ b/spine-android/app/src/main/assets/spineboy-pro.json @@ -0,0 +1,8723 @@ +{ +"skeleton": { + "hash": "dr3Kr/vMgPA", + "spine": "4.2.22", + "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", "icon": "circle" }, + { + "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", "icon": "ik" }, + { "name": "rear-leg-target", "parent": "rear-foot-target", "x": -33.91, "y": 37.34, "color": "ff3f00ff", "icon": "ik" }, + { + "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, + "inherit": "noRotationOrReflection", + "color": "ff000dff" + }, + { "name": "board-ik", "parent": "root", "x": -131.78, "y": 69.09, "color": "4c56ffff", "icon": "arrows" }, + { "name": "clipping", "parent": "root" }, + { + "name": "hoverboard-controller", + "parent": "root", + "rotation": -0.28, + "x": -329.69, + "y": 69.82, + "color": "ff0004ff", + "icon": "arrowsB" + }, + { "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, "icon": "particles" }, + { "name": "flare10", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare2", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare3", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare4", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare5", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare6", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare7", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare8", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { "name": "flare9", "parent": "portal-root", "x": -6.34, "y": -161.57, "icon": "particles" }, + { + "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", "icon": "ik" }, + { "name": "front-leg-target", "parent": "front-foot-target", "x": -28.4, "y": 29.06, "color": "ff3f00ff", "icon": "ik" }, + { + "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, + "inherit": "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, "inherit": "noRotationOrReflection" }, + { "name": "hoverboard-thruster-rear", "parent": "hoverboard-controller", "rotation": -29.2, "x": -76.47, "y": -4.88, "inherit": "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", + "icon": "muzzleFlash" + }, + { "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", "icon": "arrows" } +], +"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-android/app/src/main/assets/spineboy-pro.skel b/spine-android/app/src/main/assets/spineboy-pro.skel new file mode 100644 index 000000000..09e564b7e Binary files /dev/null and b/spine-android/app/src/main/assets/spineboy-pro.skel differ diff --git a/spine-android/app/src/main/assets/spineboy.atlas b/spine-android/app/src/main/assets/spineboy.atlas new file mode 100644 index 000000000..eca542b71 --- /dev/null +++ b/spine-android/app/src/main/assets/spineboy.atlas @@ -0,0 +1,94 @@ +spineboy.png + size: 1024, 256 + filter: Linear, Linear + scale: 0.5 +crosshair + bounds: 352, 7, 45, 45 +eye-indifferent + bounds: 862, 105, 47, 45 +eye-surprised + bounds: 505, 79, 47, 45 +front-bracer + bounds: 826, 66, 29, 40 +front-fist-closed + bounds: 786, 65, 38, 41 +front-fist-open + bounds: 710, 51, 43, 44 + rotate: 90 +front-foot + bounds: 210, 6, 63, 35 +front-shin + bounds: 665, 128, 41, 92 + rotate: 90 +front-thigh + bounds: 2, 2, 23, 56 + rotate: 90 +front-upper-arm + bounds: 250, 205, 23, 49 +goggles + bounds: 665, 171, 131, 83 +gun + bounds: 798, 152, 105, 102 +head + bounds: 2, 27, 136, 149 +hoverboard-board + bounds: 2, 178, 246, 76 +hoverboard-thruster + bounds: 722, 96, 30, 32 + rotate: 90 +hoverglow-small + bounds: 275, 81, 137, 38 +mouth-grind + bounds: 614, 97, 47, 30 +mouth-oooo + bounds: 612, 65, 47, 30 +mouth-smile + bounds: 661, 64, 47, 30 +muzzle-glow + bounds: 382, 54, 25, 25 +muzzle-ring + bounds: 275, 54, 25, 105 + rotate: 90 +muzzle01 + bounds: 911, 95, 67, 40 + rotate: 90 +muzzle02 + bounds: 792, 108, 68, 42 +muzzle03 + bounds: 956, 171, 83, 53 + rotate: 90 +muzzle04 + bounds: 275, 7, 75, 45 +muzzle05 + bounds: 140, 3, 68, 38 +neck + bounds: 250, 182, 18, 21 +portal-bg + bounds: 140, 43, 133, 133 +portal-flare1 + bounds: 554, 65, 56, 30 +portal-flare2 + bounds: 759, 112, 57, 31 + rotate: 90 +portal-flare3 + bounds: 554, 97, 58, 30 +portal-shade + bounds: 275, 121, 133, 133 +portal-streaks1 + bounds: 410, 126, 126, 128 +portal-streaks2 + bounds: 538, 129, 125, 125 +rear-bracer + bounds: 857, 67, 28, 36 +rear-foot + bounds: 663, 96, 57, 30 +rear-shin + bounds: 414, 86, 38, 89 + rotate: 90 +rear-thigh + bounds: 756, 63, 28, 47 +rear-upper-arm + bounds: 60, 5, 20, 44 + rotate: 90 +torso + bounds: 905, 164, 49, 90 diff --git a/spine-android/app/src/main/assets/spineboy.png b/spine-android/app/src/main/assets/spineboy.png new file mode 100644 index 000000000..0ea9737f3 Binary files /dev/null and b/spine-android/app/src/main/assets/spineboy.png differ diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/AnimationStateEvents.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/AnimationStateEvents.kt new file mode 100644 index 000000000..c1b507b52 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/AnimationStateEvents.kt @@ -0,0 +1,174 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import android.util.Log +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.badlogic.gdx.graphics.Color +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AnimationState(nav: NavHostController) { + + val TAG = "AnimationState" + + val controller = remember { + SpineController { controller -> + controller.skeleton.setScaleX(0.5f) + controller.skeleton.setScaleY(0.5f) + + controller.skeleton.findSlot("gun")?.color?.set(Color(1f, 0f, 0f, 1f)) + + controller.animationStateData.setDefaultMix(0.2f) + controller.animationState.setAnimation(0, "walk", true).setListener(object : AnimationState.AnimationStateListener { + override fun start(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Walk animation event start") + } + + override fun interrupt(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Walk animation event interrupt") + } + + override fun end(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Walk animation event end") + } + + override fun dispose(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Walk animation event dispose") + } + + override fun complete(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Walk animation event complete") + } + + override fun event(entry: AnimationState.TrackEntry?, event: Event?) { + Log.d(TAG, "Walk animation event event") + } + }) + controller.animationState.addAnimation(0, "jump", false, 2f) + controller.animationState.addAnimation(0, "run", true, 0f).setListener(object : AnimationState.AnimationStateListener { + override fun start(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Run animation event start") + } + + override fun interrupt(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Run animation event interrupt") + } + + override fun end(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Run animation event end") + } + + override fun dispose(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Run animation event dispose") + } + + override fun complete(entry: AnimationState.TrackEntry?) { + Log.d(TAG, "Run animation event complete") + } + + override fun event(entry: AnimationState.TrackEntry?, event: Event?) { + Log.d(TAG, "Run animation event event") + } + }) + + controller.animationState.addListener(object : AnimationState.AnimationStateListener { + override fun start(entry: AnimationState.TrackEntry?) {} + + override fun interrupt(entry: AnimationState.TrackEntry?) {} + + override fun end(entry: AnimationState.TrackEntry?) {} + + override fun dispose(entry: AnimationState.TrackEntry?) {} + + override fun complete(entry: AnimationState.TrackEntry?) {} + + override fun event(entry: AnimationState.TrackEntry?, event: Event?) { + if (event != null) { + Log.d(TAG, "User event: { name: ${event.data.name}, intValue: ${event.int}, floatValue: ${event.float}, stringValue: ${event.string} }") + } + } + }) + Log.d(TAG, "Current: ${controller.animationState.getCurrent(0)?.getAnimation()?.getName()}"); + } + } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.AnimationStateEvents.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + Column( + modifier = Modifier.padding(paddingValues), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text("See output in console!") + AndroidView( + factory = { context -> + SpineView.loadFromAssets( + "spineboy.atlas", + "spineboy-pro.json", + context, + controller + ) + } + ) + } + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/DebugRendering.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/DebugRendering.kt new file mode 100644 index 000000000..50abe1e30 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/DebugRendering.kt @@ -0,0 +1,91 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.esotericsoftware.spine.android.DebugRenderer +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DebugRendering(nav: NavHostController) { + + val debugRenderer = remember { + DebugRenderer() + } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.DebugRendering.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + AndroidView( + factory = { context -> + SpineView.loadFromAssets( + "spineboy.atlas", + "spineboy-pro.json", + context, + SpineController.Builder { controller -> + controller.animationState.setAnimation(0, "walk", true) + } + .setOnAfterPaint { controller, canvas, commands -> + debugRenderer.render(controller.drawable, canvas, commands) + } + .build() + ) + }, + modifier = Modifier.padding(paddingValues) + ) + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/DisableRendering.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/DisableRendering.kt new file mode 100644 index 000000000..af617c283 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/DisableRendering.kt @@ -0,0 +1,237 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import androidx.compose.foundation.gestures.detectDragGestures +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.layout.positionInParent +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.toSize +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.esotericsoftware.spine.android.AndroidSkeletonDrawable +import com.esotericsoftware.spine.android.AndroidTextureAtlas +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView +import com.esotericsoftware.spine.android.utils.SkeletonDataUtils +import kotlin.random.Random + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DisableRendering(nav: NavHostController) { + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.DisableRendering.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + + val visibleSpineBoys = remember { + mutableStateListOf() + } + + Column( + modifier = Modifier + .padding(paddingValues) + .padding() + .onGloballyPositioned { coordinates -> + print(coordinates.size.toSize()) + } + ) { + Column( + modifier = Modifier + .padding(8.dp) + ) { + Text("There are ${visibleSpineBoys.count()} spine boys visible. Scroll around to find the odd one out...") + Text("Rendering is disabled when the spine view moves out of the viewport, preserving CPU/GPU resources.", color = Color.Gray) + } + SpineBoys(visibleSpineBoys) + } + } +} + +@Composable +fun SpineBoys(visibleSpineBoys: MutableList) { + var boxSize by remember { mutableStateOf(Size.Zero) } + val offsetX = remember { mutableFloatStateOf(0f) } + val offsetY = remember { mutableFloatStateOf(0f) } + + Box( + modifier = Modifier + .fillMaxSize() + .clipToBounds() + .onGloballyPositioned { coordinates -> + boxSize = coordinates.size.toSize() + } + .pointerInput(Unit) { + detectDragGestures { change, dragAmount -> + change.consume() + offsetX.floatValue += dragAmount.x + offsetY.floatValue += dragAmount.y + } + } + ) { + if (boxSize != Size.Zero) { + val contentSize = boxSize * 4f + + val context = LocalContext.current + val cachedAtlas = + remember { AndroidTextureAtlas.fromAsset("spineboy.atlas", context) } + val cachedSkeletonData = remember { + SkeletonDataUtils.fromAsset( + cachedAtlas, + "spineboy-pro.json", + context + ) + } + + val spineboys = remember { + val rng = Random(System.currentTimeMillis()) + List(100) { index -> + val scale = 0.1f + rng.nextFloat() * 0.2f + val position = Offset( + rng.nextFloat() * contentSize.width, + rng.nextFloat() * contentSize.height + ) + SpineBoyData( + index, + scale, + position, + if (index == 99) "hoverboard" else "walk" + ) + } + } + + spineboys.forEach { spineBoyData -> + + val isSpineBoyVisible = remember { mutableStateOf(false) } + + Box(modifier = Modifier + .offset { + IntOffset( + (-(contentSize.width / 2) + spineBoyData.position.x + offsetX.floatValue.toInt()).toInt(), + (-(contentSize.height / 2) + spineBoyData.position.y + offsetY.floatValue.toInt()).toInt(), + ) + } + .size( + (boxSize.width * spineBoyData.scale).dp, + (boxSize.height * spineBoyData.scale).dp + ) + .onGloballyPositioned { coordinates -> + val positionInRoot = coordinates.positionInParent() + val size = coordinates.size.toSize() + + val isInViewport = positionInRoot.x < boxSize.width && + positionInRoot.x + size.width > 0 && + positionInRoot.y < boxSize.height && + positionInRoot.y + size.height > 0 + + isSpineBoyVisible.value = isInViewport + + val visibleSpineBoysAsSet = visibleSpineBoys.toMutableSet() + if (isInViewport) { + visibleSpineBoysAsSet.add(spineBoyData.id) + } else { + visibleSpineBoysAsSet.remove(spineBoyData.id) + } + visibleSpineBoys.clear() + visibleSpineBoys.addAll(visibleSpineBoysAsSet) + } + ) { + AndroidView( + factory = { ctx -> + SpineView.loadFromDrawable( + AndroidSkeletonDrawable(cachedAtlas, cachedSkeletonData), + ctx, + SpineController { + it.animationState.setAnimation( + 0, + spineBoyData.animation, + true + ) + } + ).apply { + isRendering = false + } + }, + update = { view -> + view.isRendering = isSpineBoyVisible.value + } + ) + } + } + } + } +} + +data class SpineBoyData( + val id: Int, + val scale: Float, + val position: Offset, + val animation: String +) diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/DressUp.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/DressUp.kt new file mode 100644 index 000000000..f0b1d315b --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/DressUp.kt @@ -0,0 +1,228 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.graphics.painter.BitmapPainter +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.esotericsoftware.spine.android.AndroidSkeletonDrawable +import com.esotericsoftware.spine.android.SkeletonRenderer +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DressUp(nav: NavHostController) { + + val context = LocalContext.current + val thumbnailSize = 150f + + val drawable = remember { + AndroidSkeletonDrawable.fromAsset( + "mix-and-match.atlas", + "mix-and-match-pro.skel", + context + ) + } + + val renderer = remember { + SkeletonRenderer() + } + + val customSkin = remember { + mutableStateOf(null) + } + + val skinImages = remember { + mutableStateMapOf() + } + + val selectedSkins = remember { + mutableStateMapOf() + } + + val controller = remember { + SpineController { controller -> + controller.animationState.setAnimation(0, "dance", true) + } + } + + fun toggleSkin(skinName: String) { + selectedSkins[skinName] = !(selectedSkins[skinName] ?: false) + drawable.skeleton.setSkin("default") + customSkin.value = Skin("custom-skin"); + for (selectedSkinKey in selectedSkins.keys) { + if (selectedSkins[selectedSkinKey] == true) { + val selectedSkin = drawable.skeletonData.findSkin(selectedSkinKey) + if (selectedSkin != null) customSkin.value?.addSkin(selectedSkin) + } + } + val customSkinValue = customSkin.value + if (customSkinValue != null) { + drawable.skeleton.setSkin(customSkinValue) + } + drawable.skeleton.setSlotsToSetupPose() + } + + val localDensity = LocalDensity.current + + LaunchedEffect(Unit) { + for (skin in drawable.skeletonData.getSkins()) { + if (skin.getName() == "default") continue + val skeleton = drawable.skeleton + skeleton.setSkin(skin) + skeleton.setToSetupPose() + skeleton.update(0f) + skeleton.updateWorldTransform(Skeleton.Physics.update) + skinImages[skin.getName()] = renderer.renderToBitmap( + with(localDensity) { thumbnailSize.dp.toPx() }, + with(localDensity) { thumbnailSize.dp.toPx() }, + 0xffffffff.toInt(), + skeleton, + ).asImageBitmap() + selectedSkins[skin.getName()] = false + } + toggleSkin("full-skins/girl"); + } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.DressUp.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + Row( + modifier = Modifier + .padding(paddingValues) + ) { + Column( + modifier = Modifier + .width(thumbnailSize.dp) + .verticalScroll(rememberScrollState()) + ) { + skinImages.keys.forEach { skinName -> + Box(modifier = Modifier + .clickable { + toggleSkin(skinName) + } + .then( + if (selectedSkins[skinName] == true) { + Modifier + } else { + Modifier.grayScale() + } + ) + ) { + Image( + painter = BitmapPainter(skinImages[skinName]!!), + contentDescription = null + ) + } + } + } + Column( + modifier = Modifier + .clipToBounds() + ) { + AndroidView( + factory = { context -> + SpineView.loadFromDrawable(drawable, context, controller) + } + ) + } + } + } +} + +fun Modifier.grayScale(): Modifier { + val saturationMatrix = ColorMatrix().apply { setToSaturation(0f) } + val saturationFilter = ColorFilter.colorMatrix(saturationMatrix) + val paint = Paint().apply { colorFilter = saturationFilter } + + return drawWithCache { + val canvasBounds = Rect(Offset.Zero, size) + onDrawWithContent { + drawIntoCanvas { + it.saveLayer(canvasBounds, paint) + drawContent() + it.restore() + } + } + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/IKFollowing.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/IKFollowing.kt new file mode 100644 index 000000000..d49bc01b8 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/IKFollowing.kt @@ -0,0 +1,140 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import android.graphics.Point +import androidx.compose.foundation.gestures.detectDragGestures +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.badlogic.gdx.math.Vector2 +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView +import com.esotericsoftware.spine.android.bounds.Alignment + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun IKFollowing(nav: NavHostController) { + + val containerHeight = remember { mutableIntStateOf(0) } + val dragPosition = remember { mutableStateOf(Point(0, 0)) } + val crossHairPosition = remember { mutableStateOf(null) } + + val controller = remember { + SpineController.Builder { controller -> + controller.animationState.setAnimation(0, "walk", true) + controller.animationState.setAnimation(1, "aim", true) + } + .setOnAfterUpdateWorldTransforms { + val worldPosition = crossHairPosition.value ?: return@setOnAfterUpdateWorldTransforms + val skeleton = it.skeleton + val bone = skeleton.findBone("crosshair") ?: return@setOnAfterUpdateWorldTransforms + val parent = bone.parent ?: return@setOnAfterUpdateWorldTransforms + val position = parent.worldToLocal(Vector2(worldPosition.x.toFloat(), worldPosition.y.toFloat())) + bone.x = position.x + bone.y = position.y + } + .build() + } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.IKFollowing.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + Box(modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .onGloballyPositioned { coordinates -> + containerHeight.intValue = coordinates.size.height + } + .pointerInput(Unit) { + detectDragGestures( + onDragStart = { offset -> + dragPosition.value = Point(offset.x.toInt(), offset.y.toInt()) + }, + onDrag = { _, dragAmount -> + dragPosition.value = Point( + (dragPosition.value.x + dragAmount.x).toInt(), + (dragPosition.value.y + dragAmount.y).toInt() + ) + val invertedYDragPosition = Point( + dragPosition.value.x, + containerHeight.intValue - dragPosition.value.y, + ) + crossHairPosition.value = controller.toSkeletonCoordinates( + invertedYDragPosition + ) + }, + ) + } + ) { + AndroidView( + factory = { context -> + SpineView.loadFromAssets( + "spineboy.atlas", + "spineboy-pro.json", + context, + controller + ).apply { + alignment = Alignment.CENTER_LEFT + } + } + ) + } + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/MainActivity.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/MainActivity.kt new file mode 100644 index 000000000..c9d537cf7 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/MainActivity.kt @@ -0,0 +1,220 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.Card +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.esotericsoftware.spine.ui.theme.SpineAndroidExamplesTheme + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + AppContent() + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AppContent() { + val navController = rememberNavController() + + SpineAndroidExamplesTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + NavHost( + navController = navController, + startDestination = Destination.Samples.route + ) { + composable( + Destination.Samples.route + ) { + Scaffold( + topBar = { TopAppBar(title = { Text(text = Destination.Samples.title) }) } + ) { paddingValues -> + Samples( + navController, + listOf( + Destination.SimpleAnimation, + Destination.PlayPause, + Destination.AnimationStateEvents, + Destination.DebugRendering, + Destination.DressUp, + Destination.IKFollowing, + Destination.Physics, + Destination.DisableRendering + ), + paddingValues + ) + } + } + + composable( + Destination.SimpleAnimation.route + ) { + SimpleAnimation(navController) + } + + composable( + Destination.PlayPause.route + ) { + PlayPause(navController) + } + + composable( + Destination.AnimationStateEvents.route + ) { + AnimationState(navController) + } + + composable( + Destination.DebugRendering.route + ) { + DebugRendering(navController) + } + + composable( + Destination.DressUp.route + ) { + DressUp(navController) + } + + composable( + Destination.IKFollowing.route + ) { + IKFollowing(navController) + } + + composable( + Destination.Physics.route + ) { + Physics(navController) + } + + composable( + Destination.DisableRendering.route + ) { + DisableRendering(navController) + } + } + } + } +} + +@Composable +fun Samples( + nav: NavHostController, + samples: List, + paddingValues: PaddingValues +) { + LazyColumn( + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier + .padding(8.dp) + .padding(paddingValues) + ) { + item { + Text(text = "Kotlin + Jetpack Compose", Modifier.padding(8.dp)) + } + + samples.forEach { + item { + Card( + Modifier + .fillMaxWidth() + .clickable(onClick = { nav.navigate(it.route) }), + shape = MaterialTheme.shapes.large + ) { + Text(text = it.title, Modifier.padding(24.dp)) + } + } + } + + item { + Text(text = "Java + XML", Modifier.padding(8.dp)) + } + + item { + Card( + Modifier + .fillMaxWidth() + .clickable(onClick = { + nav.context.startActivity( + Intent( + nav.context, + SimpleAnimationActivity::class.java + ) + ) + }), + shape = MaterialTheme.shapes.large + ) { + Text(text = "Simple Animation", Modifier.padding(24.dp)) + } + } + } +} + +sealed class Destination(val route: String, val title: String) { + data object Samples: Destination("samples", "Spine Android Examples") + data object SimpleAnimation : Destination("simpleAnimation", "Simple Animation") + data object PlayPause : Destination("playPause", "Play/Pause") + data object DebugRendering: Destination("debugRendering", "Debug Renderer") + data object AnimationStateEvents : Destination("animationStateEvents", "Animation State Listener") + data object DressUp : Destination("dressUp", "Dress Up") + data object IKFollowing : Destination("ikFollowing", "IK Following") + data object Physics: Destination("physics", "Physics (drag anywhere)") + data object DisableRendering: Destination("disableRendering", "Disable Rendering") +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/Physics.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/Physics.kt new file mode 100644 index 000000000..a9c39348a --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/Physics.kt @@ -0,0 +1,153 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import android.graphics.Point +import androidx.compose.foundation.gestures.detectDragGestures +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Physics(nav: NavHostController) { + + val containerHeight = remember { mutableIntStateOf(0) } + val dragPosition = remember { mutableStateOf(Point(0, 0)) } + + val mousePosition = remember { mutableStateOf(null) } + val lastMousePosition = remember { mutableStateOf(null) } + + val controller = remember { + SpineController.Builder { controller -> + controller.animationState.setAnimation(0, "eyeblink-long", true) + controller.animationState.setAnimation(1, "wings-and-feet", true) + } + .setOnAfterUpdateWorldTransforms { controller -> + val lastMousePositionValue = lastMousePosition.value + if (lastMousePositionValue == null) { + lastMousePosition.value = mousePosition.value + return@setOnAfterUpdateWorldTransforms + } + val mousePositionValue = mousePosition.value ?: return@setOnAfterUpdateWorldTransforms + + val dx = mousePositionValue.x - lastMousePositionValue.x + val dy = mousePositionValue.y - lastMousePositionValue.y + val position = Point( + controller.skeleton.x.toInt(), + controller.skeleton.y.toInt() + ) + position.x += dx + position.y += dy + controller.skeleton.setPosition(position.x.toFloat(), position.y.toFloat()); + lastMousePosition.value = mousePositionValue + } + .build() + } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.Physics.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + Box(modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .onGloballyPositioned { coordinates -> + containerHeight.intValue = coordinates.size.height + } + .pointerInput(Unit) { + detectDragGestures( + onDragStart = { offset -> + dragPosition.value = Point(offset.x.toInt(), offset.y.toInt()) + }, + onDrag = { _, dragAmount -> + dragPosition.value = Point( + (dragPosition.value.x + dragAmount.x).toInt(), + (dragPosition.value.y + dragAmount.y).toInt() + ) + val invertedYDragPosition = Point( + dragPosition.value.x, + containerHeight.intValue - dragPosition.value.y, + ) + mousePosition.value = controller.toSkeletonCoordinates( + invertedYDragPosition + ) + }, + onDragEnd = { -> + mousePosition.value = null; + lastMousePosition.value = null; + } + ) + } + ) { + AndroidView( + factory = { context -> + SpineView.loadFromAssets( + "celestial-circus.atlas", + "celestial-circus-pro.skel", + context, + controller + ) + }, + modifier = Modifier.padding(paddingValues) + ) + } + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/PlayPause.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/PlayPause.kt new file mode 100644 index 000000000..f441d74d0 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/PlayPause.kt @@ -0,0 +1,99 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView +import com.esotericsoftware.spine.android.bounds.SkinAndAnimationBounds + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun PlayPause( + nav: NavHostController +) { + val controller = remember { + SpineController { controller -> + controller.animationState.setAnimation(0, "flying", true) + } + } + + val isPlaying = remember { mutableStateOf(controller.isPlaying) } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.PlayPause.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + }, + actions = { + Button(onClick = { + if (controller.isPlaying) controller.pause() else controller.resume() + isPlaying.value = controller.isPlaying + }) { + Text(text = if (isPlaying.value) "Pause" else "Play") + } + } + ) + } + ) { paddingValues -> + + AndroidView( + factory = { ctx -> + SpineView.Builder(ctx, controller) + .setLoadFromAssets("dragon.atlas", "dragon-ess.skel") + .setBoundsProvider(SkinAndAnimationBounds("flying")) + .build() + }, + modifier = Modifier.padding(paddingValues) + ) + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/SimpleAnimation.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/SimpleAnimation.kt new file mode 100644 index 000000000..2f287fff8 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/SimpleAnimation.kt @@ -0,0 +1,91 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine + +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.viewinterop.AndroidView +import androidx.navigation.NavHostController +import com.esotericsoftware.spine.android.SpineController +import com.esotericsoftware.spine.android.SpineView +import java.io.File +import java.net.URL + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SimpleAnimation(nav: NavHostController) { + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = Destination.SimpleAnimation.title) }, + navigationIcon = { + IconButton({ nav.navigateUp() }) { + Icon( + Icons.Rounded.ArrowBack, + null, + ) + } + } + ) + } + ) { paddingValues -> + AndroidView( + factory = { context -> + SpineView.loadFromAssets( + "spineboy.atlas", + "spineboy-pro.json", + context, + SpineController { + it.animationState.setAnimation(0, "walk", true) + } + ) +// SpineView.loadFromHttp( +// URL("https://raw.githubusercontent.com/EsotericSoftware/spine-runtimes/4.2/examples/spineboy/export/spineboy.atlas"), +// URL("https://raw.githubusercontent.com/EsotericSoftware/spine-runtimes/4.2/examples/spineboy/export/spineboy-pro.skel"), +// context.filesDir, +// context, +// SpineController { +// it.animationState.setAnimation(0, "walk", true) +// } +// ) + }, + modifier = Modifier.padding(paddingValues) + ) + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/SimpleAnimationActivity.java b/spine-android/app/src/main/java/com/esotericsoftware/spine/SimpleAnimationActivity.java new file mode 100644 index 000000000..51f50d8f8 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/SimpleAnimationActivity.java @@ -0,0 +1,76 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine; + +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import com.esotericsoftware.spine.android.SpineController; +import com.esotericsoftware.spine.android.SpineView; + +public class SimpleAnimationActivity extends AppCompatActivity { + /** @noinspection FieldCanBeLocal */ + private SpineView spineView; + /** @noinspection FieldCanBeLocal */ + private SpineController spineController; + + @Override + protected void onCreate (Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_simple_animation); + + // Set up the toolbar + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + if (getSupportActionBar() != null) { + getSupportActionBar().setTitle("Simple Animation"); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + spineView = findViewById(R.id.spineView); + spineController = new SpineController(controller -> controller.getAnimationState().setAnimation(0, "walk", true)); + + spineView.setController(spineController); + spineView.loadFromAsset("spineboy.atlas", "spineboy-pro.json"); + } + + @Override + public boolean onOptionsItemSelected (MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Color.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Color.kt new file mode 100644 index 000000000..fcc46f94d --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Color.kt @@ -0,0 +1,40 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Theme.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Theme.kt new file mode 100644 index 000000000..f27504a29 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Theme.kt @@ -0,0 +1,99 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun SpineAndroidExamplesTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Type.kt b/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Type.kt new file mode 100644 index 000000000..5a9692672 --- /dev/null +++ b/spine-android/app/src/main/java/com/esotericsoftware/spine/ui/theme/Type.kt @@ -0,0 +1,63 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +package com.esotericsoftware.spine.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/spine-android/app/src/main/res/drawable/ic_launcher_background.xml b/spine-android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 000000000..07d5da9cb --- /dev/null +++ b/spine-android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spine-android/app/src/main/res/drawable/ic_launcher_foreground.xml b/spine-android/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 000000000..2b068d114 --- /dev/null +++ b/spine-android/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/spine-android/app/src/main/res/drawable/img.png b/spine-android/app/src/main/res/drawable/img.png new file mode 100644 index 000000000..1033d1ed8 Binary files /dev/null and b/spine-android/app/src/main/res/drawable/img.png differ diff --git a/spine-android/app/src/main/res/layout/activity_simple_animation.xml b/spine-android/app/src/main/res/layout/activity_simple_animation.xml new file mode 100644 index 000000000..b49d6a405 --- /dev/null +++ b/spine-android/app/src/main/res/layout/activity_simple_animation.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/spine-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/spine-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 000000000..6f3b755bf --- /dev/null +++ b/spine-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/spine-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/spine-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 000000000..6f3b755bf --- /dev/null +++ b/spine-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/spine-android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/spine-android/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 000000000..c209e78ec Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/spine-android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/spine-android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 000000000..b2dfe3d1b Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/spine-android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/spine-android/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 000000000..4f0f1d64e Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/spine-android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/spine-android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 000000000..62b611da0 Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/spine-android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/spine-android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 000000000..948a3070f Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/spine-android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/spine-android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 000000000..1b9a6956b Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/spine-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/spine-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 000000000..28d4b77f9 Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/spine-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/spine-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 000000000..9287f5083 Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/spine-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/spine-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 000000000..aa7d6427e Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/spine-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/spine-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 000000000..9126ae37c Binary files /dev/null and b/spine-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/spine-android/app/src/main/res/values/colors.xml b/spine-android/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..f8c6127d3 --- /dev/null +++ b/spine-android/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/spine-android/app/src/main/res/values/strings.xml b/spine-android/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..4c4059fd2 --- /dev/null +++ b/spine-android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Spine Android Examples + \ No newline at end of file diff --git a/spine-android/app/src/main/res/values/themes.xml b/spine-android/app/src/main/res/values/themes.xml new file mode 100644 index 000000000..bbe8ed79b --- /dev/null +++ b/spine-android/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + + + + + +

Animation State Events

+

Open the console in the developer tools to view events logs.

+ + + + + + \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/example/assets/celestial-circus-pro.json b/spine-ts/spine-canvaskit/example/assets/celestial-circus-pro.json new file mode 100644 index 000000000..1a7eebab0 --- /dev/null +++ b/spine-ts/spine-canvaskit/example/assets/celestial-circus-pro.json @@ -0,0 +1,3758 @@ +{ +"skeleton": { + "hash": "FsTlpSGjt5g", + "spine": "4.2.22", + "x": -755, + "y": -556.02, + "width": 1332, + "height": 2365.02, + "images": "./images/", + "audio": "" +}, +"bones": [ + { "name": "root" }, + { "name": "cloud", "parent": "root", "y": 1580, "color": "91aaebff", "icon": "circle" }, + { "name": "swing-top", "parent": "cloud", "length": 1040.94, "rotation": -90, "y": 4.09, "color": "afc1eeff" }, + { "name": "swing-bottom", "parent": "swing-top", "length": 520.47, "x": 1040.94, "color": "afc1eeff" }, + { + "name": "bench-front", + "parent": "swing-bottom", + "rotation": 90, + "x": 528.6, + "y": -170.65, + "color": "afc1eeff", + "icon": "diamond" + }, + { "name": "bench-back", "parent": "bench-front", "x": 314.34, "y": 66.88, "color": "34497dff", "icon": "diamond" }, + { + "name": "rope-front", + "parent": "swing-top", + "rotation": 90, + "x": 215.22, + "y": -172.32, + "color": "afc1eeff", + "icon": "diamond" + }, + { + "name": "rope-back", + "parent": "swing-top", + "rotation": 90, + "x": 153.36, + "y": 157.07, + "color": "34497dff", + "icon": "diamond" + }, + { "name": "body-bottom", "parent": "bench-front", "x": 172.22, "y": 170.54, "color": "ff9b1aff", "icon": "diamondB" }, + { + "name": "body-down", + "parent": "body-bottom", + "length": 144.53, + "rotation": 90, + "x": 1.67, + "y": 3.34, + "color": "ff9b1aff" + }, + { "name": "body-up", "parent": "body-down", "length": 222.38, "x": 142.12, "y": -0.84, "color": "ff9b1aff" }, + { + "name": "leg-back", + "parent": "body-bottom", + "length": 337.6, + "rotation": -43.22, + "x": 81.18, + "y": 17, + "color": "1540beff" + }, + { "name": "leg-back-down", "parent": "leg-back", "length": 393.2, "rotation": -28.55, "x": 337.6, "color": "1540beff" }, + { "name": "foot-back", "parent": "leg-back-down", "length": 136.87, "rotation": 1.38, "x": 393.2, "color": "1540beff" }, + { + "name": "leg-front", + "parent": "body-bottom", + "length": 325.03, + "rotation": -28.9, + "x": -50.72, + "y": -36.36, + "color": "d10606ff" + }, + { "name": "leg-front-down", "parent": "leg-front", "length": 407.97, "rotation": -44.64, "x": 325.03, "color": "d10606ff" }, + { "name": "foot-front", "parent": "leg-front-down", "length": 174.76, "rotation": 23.03, "x": 407.97, "color": "d10606ff" }, + { + "name": "chest-control", + "parent": "body-up", + "rotation": -0.22, + "x": 135.95, + "y": -81.51, + "color": "ff9b1aff", + "icon": "arrows" + }, + { "name": "neck", "parent": "body-up", "length": 98.45, "x": 296.95, "y": 23.58, "color": "ff9b1aff" }, + { + "name": "jabot", + "parent": "body-up", + "length": 86.81, + "rotation": -167.47, + "x": 284.11, + "y": -5.52, + "color": "ff9b1aff" + }, + { "name": "face", "parent": "neck", "length": 254.23, "x": 95.02, "y": 10.27, "color": "ff9b1aff" }, + { "name": "face-control", "parent": "face", "x": 25.68, "y": -99.3, "color": "ff9b1aff", "icon": "arrowsB" }, + { "name": "face-inverse", "parent": "face", "x": 135.25, "y": 152.37, "color": "ff9b1aff", "icon": "warning" }, + { + "name": "hat-front", + "parent": "face", + "length": 88.84, + "rotation": 25.08, + "x": 216.57, + "y": 39.38, + "color": "ffe719ff" + }, + { + "name": "feathers-front", + "parent": "hat-front", + "length": 125.88, + "rotation": -23.52, + "x": 19.98, + "y": -76.45, + "color": "ffe719ff" + }, + { "name": "feathers-front-top", "parent": "feathers-front", "length": 120.64, "rotation": 46.61, "x": 125.88, "color": "ffe719ff" }, + { + "name": "hair-back", + "parent": "face-inverse", + "length": 468.65, + "rotation": 180, + "x": -6.39, + "y": -102.85, + "color": "561d8ea9" + }, + { "name": "hair-back-down", "parent": "hair-back", "length": 234.32, "x": 468.65, "color": "561d8ea9" }, + { "name": "face-holder", "parent": "face", "x": 59.16, "y": -82.67, "color": "ff9b1aff", "icon": "square" }, + { + "name": "fringe-side-front", + "parent": "face-holder", + "length": 214.4, + "rotation": 180, + "x": 111.88, + "y": 110.79, + "color": "c181e8ff" + }, + { + "name": "fringe-side-back", + "parent": "face-holder", + "length": 221.68, + "rotation": 180, + "x": 106.6, + "y": -43.08, + "color": "9f19ffff" + }, + { "name": "arm-front-up-holder", "parent": "body-up", "x": 237.74, "y": 145.38, "color": "ff1919ff", "icon": "arrowsB" }, + { "name": "arm-front-up", "parent": "arm-front-up-holder", "length": 223.61, "rotation": 155.09, "x": 0.6, "color": "ff1919ff" }, + { "name": "arm-back-up-holder", "parent": "body-up", "x": 263.54, "y": -112.02, "color": "19b2ffff", "icon": "warning" }, + { "name": "arm-back-up", "parent": "arm-back-up-holder", "length": 231.75, "rotation": -155.69, "color": "19b2ffff" }, + { + "name": "wing-front", + "parent": "body-down", + "length": 441.84, + "rotation": 51.84, + "x": 184.85, + "y": 60.03, + "color": "19ffb2ff" + }, + { "name": "wing-front-tip", "parent": "wing-front", "length": 401.17, "rotation": 10.15, "x": 441.84, "color": "19ffb2ff" }, + { + "name": "wing-back", + "parent": "body-down", + "length": 187.48, + "rotation": -37.42, + "x": 188.23, + "y": -9.9, + "color": "0fab73ff" + }, + { "name": "wing-back-tip", "parent": "wing-back", "length": 414.74, "rotation": 15.88, "x": 187.48, "color": "0fab73ff" }, + { + "name": "sock-bow", + "parent": "leg-front-down", + "length": 48.74, + "rotation": -14.1, + "x": 258.61, + "y": -45.08, + "color": "d10606ff" + }, + { + "name": "skirt-back", + "parent": "bench-front", + "length": 282.06, + "rotation": -105.78, + "x": -169.75, + "y": 31.39, + "color": "abe323ff" + }, + { + "name": "skirt-front", + "parent": "bench-back", + "length": 243.95, + "rotation": -62.03, + "x": 191.48, + "y": 67.98, + "color": "00842eff" + }, + { "name": "underskirt-back", "parent": "skirt-back", "x": 294.81, "y": 0.61, "color": "abe323ff" }, + { "name": "underskirt-front", "parent": "skirt-front", "x": 249.28, "y": -0.54, "color": "00842eff" }, + { "name": "mouth", "parent": "face-holder", "x": -71.7, "y": 11.81, "color": "ff9b1aff", "icon": "mouth" }, + { "name": "eye-white-front", "parent": "face-holder", "x": 2, "y": 55.83, "color": "fff019ff", "icon": "eye" }, + { "name": "pupil-front", "parent": "eye-white-front", "x": 2.39, "y": -1.65, "color": "fff019ff", "icon": "star" }, + { + "name": "eyelashes-top-front", + "parent": "eye-white-front", + "rotation": -5.82, + "x": 23.09, + "y": -5.15, + "color": "fff019ff", + "icon": "arrowLeftRight" + }, + { "name": "eyelashes-down-front", "parent": "eye-white-front", "x": -19.83, "y": 8.85, "color": "fff019ff", "icon": "arrowLeftRight" }, + { "name": "eye-white-back", "parent": "face-holder", "x": -0.34, "y": -36.94, "color": "c99d19ff", "icon": "eye" }, + { "name": "pupil-back", "parent": "eye-white-back", "x": 2.17, "y": -1.08, "color": "c99d19ff", "icon": "star" }, + { "name": "eyelashes-top-back", "parent": "eye-white-back", "x": 17.02, "y": -2.38, "color": "c99d19ff", "icon": "arrowLeftRight" }, + { "name": "eyelashes-down-back", "parent": "eye-white-back", "x": -17.56, "y": -0.43, "color": "c99d19ff", "icon": "arrowLeftRight" }, + { "name": "star1", "parent": "cloud", "x": -244.61, "y": 44.37, "color": "ffe12fff", "icon": "star" }, + { "name": "star2", "parent": "cloud", "x": 161.71, "y": 44.37, "color": "ffe12fff", "icon": "star" }, + { "name": "star3", "parent": "cloud", "x": -120.79, "y": -83.12, "color": "ffe12fff", "icon": "star" }, + { "name": "star4", "parent": "cloud", "x": 19.54, "y": 117.75, "color": "ffe12fff", "icon": "star" }, + { "name": "star5", "parent": "cloud", "x": -216.18, "y": -117.05, "color": "ffe12fff", "icon": "star" }, + { "name": "star6", "parent": "cloud", "x": 204.82, "y": -110.63, "color": "ffe12fff", "icon": "star" }, + { "name": "cloud-perspective", "parent": "cloud", "y": 25.92, "color": "d9e2faff", "icon": "arrowsB" } +], +"slots": [ + { "name": "underskirt-back", "bone": "body-bottom", "attachment": "underskirt-back" }, + { "name": "wing-back", "bone": "wing-back", "attachment": "wing-back" }, + { "name": "wing-front", "bone": "wing-front", "attachment": "wing-front" }, + { "name": "hat/feathers-back", "bone": "feathers-front", "attachment": "feathers-back" }, + { "name": "hat/feathers-front", "bone": "feathers-front", "attachment": "feathers-front" }, + { "name": "hat/hat-back", "bone": "hat-front", "attachment": "hat-back" }, + { "name": "hat/hat-front", "bone": "hat-front", "attachment": "hat-front" }, + { "name": "bench", "bone": "bench-front", "attachment": "bench" }, + { "name": "head-back", "bone": "face", "attachment": "head-back" }, + { "name": "hair-back/hair-back-6", "bone": "hair-back", "attachment": "hair-back-6" }, + { "name": "hair-back/hair-back-5", "bone": "hair-back", "attachment": "hair-back-5" }, + { "name": "hair-back/hair-back-4", "bone": "hair-back", "attachment": "hair-back-4" }, + { "name": "hair-back/hair-back-3", "bone": "hair-back", "attachment": "hair-back-3" }, + { "name": "hair-back/hair-back-2", "bone": "hair-back", "attachment": "hair-back-2" }, + { "name": "hair-back/hair-back-1", "bone": "hair-back", "attachment": "hair-back-1" }, + { "name": "arm-back-up", "bone": "arm-back-up-holder", "attachment": "arm-back-up" }, + { "name": "arm-back-down", "bone": "arm-back-up", "attachment": "arm-back-down" }, + { "name": "cloud-back", "bone": "cloud", "attachment": "cloud-back" }, + { "name": "rope-back", "bone": "rope-back", "attachment": "rope-back" }, + { "name": "body-bottom", "bone": "body-down", "attachment": "body-bottom" }, + { "name": "leg-back", "bone": "leg-back", "attachment": "leg-back" }, + { "name": "leg-front", "bone": "leg-front", "attachment": "leg-front" }, + { "name": "sock-bow", "bone": "sock-bow", "attachment": "sock-bow" }, + { "name": "body-top", "bone": "body-up", "attachment": "body-top" }, + { "name": "chest", "bone": "body-up", "attachment": "chest" }, + { "name": "arm-front-up", "bone": "arm-front-up", "attachment": "arm-front-up" }, + { "name": "neck", "bone": "neck", "attachment": "neck" }, + { "name": "collar", "bone": "body-up", "attachment": "collar" }, + { "name": "jabot", "bone": "jabot", "attachment": "jabot" }, + { "name": "logo-brooch", "bone": "body-up", "attachment": "logo-brooch" }, + { "name": "face/fringe-side-back", "bone": "fringe-side-back", "attachment": "fringe-side-back" }, + { "name": "face/face", "bone": "face", "attachment": "face" }, + { "name": "face/ear", "bone": "face", "attachment": "ear" }, + { "name": "face/eye-white-back", "bone": "eye-white-back", "attachment": "eye-white-back" }, + { "name": "face/eye-white-front", "bone": "eye-white-front", "attachment": "eye-white-front" }, + { "name": "face/nose", "bone": "face-holder", "attachment": "nose", "blend": "multiply" }, + { "name": "face/mouth", "bone": "mouth", "attachment": "mouth", "blend": "multiply" }, + { "name": "face/eyelashes-down-back", "bone": "eyelashes-down-back", "attachment": "eyelashes-down-back", "blend": "multiply" }, + { "name": "face/eyelashes-down-front", "bone": "eyelashes-down-front", "attachment": "eyelashes-down-front" }, + { "name": "face/pupil-back", "bone": "pupil-back", "attachment": "pupil-back" }, + { "name": "face/eye-reflex-back", "bone": "pupil-back", "attachment": "eye-reflex-back" }, + { "name": "face/pupil-front", "bone": "pupil-front", "attachment": "pupil-front" }, + { "name": "face/eye-reflex-front", "bone": "pupil-front", "attachment": "eye-reflex-front" }, + { "name": "face/eyelashes-top-back", "bone": "eyelashes-top-back", "attachment": "eyelashes-top-back", "blend": "multiply" }, + { "name": "face/eyelashes-top-front", "bone": "eyelashes-top-front", "attachment": "eyelashes-top-front" }, + { "name": "face/eye-front-shadow", "bone": "eye-white-front", "attachment": "eye-front-shadow", "blend": "multiply" }, + { "name": "face/eye-back-shadow", "bone": "eye-white-back", "attachment": "eye-back-shadow", "blend": "multiply" }, + { "name": "face/nose-shadow", "bone": "face-holder", "attachment": "nose-shadow", "blend": "multiply" }, + { "name": "face/nose-highlight", "bone": "face-holder", "attachment": "nose-highlight" }, + { "name": "face/fringe-front/fringe-middle-back", "bone": "face", "attachment": "fringe-middle-back" }, + { "name": "face/fringe-front/fringe-middle-front", "bone": "face", "attachment": "fringe-middle-front" }, + { "name": "face/fringe-front/fringe-side-front", "bone": "fringe-side-front", "attachment": "fringe-side-front" }, + { "name": "face/hair-hat-shadow", "bone": "face", "attachment": "hair-hat-shadow", "blend": "multiply" }, + { "name": "underskirt", "bone": "underskirt-back", "attachment": "underskirt" }, + { "name": "skirt", "bone": "skirt-front", "attachment": "skirt" }, + { "name": "spine-logo-body", "bone": "body-up", "attachment": "spine-logo-body" }, + { "name": "arm-front-down", "bone": "arm-front-up", "attachment": "arm-front-down" }, + { "name": "rope-front", "bone": "rope-front", "attachment": "rope-front" }, + { "name": "rope-front-bottom", "bone": "bench-front", "attachment": "rope-front-bottom" }, + { "name": "glove-bottom-back", "bone": "bench-back", "attachment": "glove-bottom-back" }, + { "name": "hand-back", "bone": "bench-back", "attachment": "hand-back" }, + { "name": "glove-bottom-front", "bone": "bench-front", "attachment": "glove-bottom-front" }, + { "name": "hand-front", "bone": "bench-front", "attachment": "hand-front" }, + { "name": "cloud-front", "bone": "cloud", "attachment": "cloud-front" }, + { "name": "stars/star1", "bone": "star1" }, + { "name": "stars/star2", "bone": "star2" }, + { "name": "stars/star3", "bone": "star3" }, + { "name": "stars/star4", "bone": "star4" }, + { "name": "stars/star5", "bone": "star5" }, + { "name": "stars/star6", "bone": "star6" } +], +"transform": [ + { + "name": "girl/face-control", + "order": 9, + "bones": [ "face-holder" ], + "target": "face-control", + "x": 33.48, + "y": 16.63, + "mixRotate": 0, + "mixX": 0.8, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "girl/head-control", + "order": 8, + "bones": [ "face-inverse" ], + "target": "face-control", + "x": 109.57, + "y": 251.66, + "mixRotate": 0, + "mixX": -0.5, + "mixScaleX": 0, + "mixShearY": 0 + }, + { + "name": "girl/shoulders-perspective", + "order": 6, + "bones": [ "arm-back-up-holder" ], + "target": "arm-front-up-holder", + "x": 25.8, + "y": -257.4, + "mixRotate": 0, + "mixX": -1, + "mixScaleX": 0, + "mixShearY": 0 + } +], +"physics": [ + { + "name": "bench-back", + "order": 31, + "bone": "bench-back", + "x": 0.4949, + "y": 0.4579, + "limit": 1500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "bench-front", + "order": 2, + "bone": "bench-front", + "x": 0.1279, + "y": 0.2256, + "inertia": 0.4071, + "strength": 81.4, + "damping": 0.792 + }, + { + "name": "cloud-perspective", + "order": 32, + "bone": "cloud-perspective", + "x": 1, + "y": 1, + "limit": 500, + "inertia": 0.25, + "damping": 0.85, + "windGlobal": true + }, + { "name": "swing-bottom", "order": 1, "bone": "swing-bottom", "rotate": 1, "inertia": 0.5, "damping": 0.85 }, + { "name": "swing-top", "bone": "swing-top", "rotate": 1, "limit": 7000, "inertia": 0.5, "damping": 0.85 }, + { + "name": "girl/hair/fringe-side-back", + "order": 26, + "bone": "fringe-side-back", + "rotate": 1, + "scaleX": 0.6033, + "limit": 1500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "girl/hair/fringe-side-front", + "order": 25, + "bone": "fringe-side-front", + "rotate": 1, + "scaleX": 0.6033, + "limit": 1500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "girl/hair/hair-back", + "order": 23, + "bone": "hair-back", + "rotate": 1, + "limit": 1500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "girl/hair/hair-back-down", + "order": 24, + "bone": "hair-back-down", + "x": 1, + "y": 1, + "rotate": 1, + "scaleX": 0.3641, + "limit": 1500, + "inertia": 0.7345, + "damping": 0.8142, + "windGlobal": true + }, + { + "name": "girl/legs/foot-back", + "order": 22, + "bone": "foot-back", + "rotate": 1, + "limit": 1500, + "inertia": 0.1593, + "damping": 0.85 + }, + { + "name": "girl/legs/foot-front", + "order": 20, + "bone": "foot-front", + "rotate": 1, + "limit": 1500, + "inertia": 0.1593, + "damping": 0.85 + }, + { + "name": "girl/legs/leg-back-down", + "order": 21, + "bone": "leg-back-down", + "rotate": 1, + "limit": 1500, + "inertia": 0.8496, + "damping": 0.85 + }, + { + "name": "girl/legs/leg-front-down", + "order": 18, + "bone": "leg-front-down", + "rotate": 1, + "limit": 1500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "girl/legs/sock-bow", + "order": 19, + "bone": "sock-bow", + "rotate": 1, + "limit": 1500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "girl/skirt/skirt-back", + "order": 27, + "bone": "skirt-back", + "rotate": 1, + "limit": 1500, + "inertia": 0.3805, + "strength": 113.3, + "damping": 0.8982, + "mass": 2.27 + }, + { + "name": "girl/skirt/skirt-front", + "order": 29, + "bone": "skirt-front", + "rotate": 1, + "limit": 1500, + "inertia": 0.3805, + "strength": 113.3, + "damping": 0.8982, + "mass": 2.27 + }, + { + "name": "girl/skirt/underskirt-back", + "order": 28, + "bone": "underskirt-back", + "x": 0.3737, + "y": 0.3737, + "limit": 100, + "inertia": 0.5, + "strength": 164.6, + "damping": 0.85, + "windGlobal": true + }, + { + "name": "girl/skirt/underskirt-front", + "order": 30, + "bone": "underskirt-front", + "x": 0.3737, + "y": 0.3737, + "limit": 100, + "inertia": 0.5, + "strength": 164.6, + "damping": 0.85, + "windGlobal": true + }, + { + "name": "girl/wings/wing-back", + "order": 16, + "bone": "wing-back", + "rotate": 0.4105, + "shearX": 0.1602, + "limit": 1600, + "inertia": 0.5, + "strength": 164.6, + "damping": 0.85 + }, + { + "name": "girl/wings/wing-back-tip", + "order": 17, + "bone": "wing-back-tip", + "rotate": 1, + "limit": 1600, + "inertia": 0.5, + "damping": 0.85, + "windGlobal": true + }, + { + "name": "girl/wings/wing-front", + "order": 14, + "bone": "wing-front", + "rotate": 0.4105, + "shearX": 0.1602, + "limit": 1600, + "inertia": 0.5, + "strength": 164.6, + "damping": 0.85 + }, + { + "name": "girl/wings/wing-front-tip", + "order": 15, + "bone": "wing-front-tip", + "rotate": 1, + "limit": 1600, + "inertia": 0.5, + "damping": 0.85, + "windGlobal": true + }, + { + "name": "girl/arm-front-up-holder", + "order": 5, + "bone": "arm-front-up-holder", + "x": 0.6522, + "y": 0.1359, + "limit": 500, + "inertia": 0.5, + "damping": 0.85 + }, + { + "name": "girl/body-down", + "order": 3, + "bone": "body-down", + "rotate": 1, + "limit": 1500, + "inertia": 0.1195, + "damping": 0.85 + }, + { + "name": "girl/body-up", + "order": 4, + "bone": "body-up", + "rotate": 0.3098, + "limit": 1500, + "inertia": 0.2257, + "damping": 0.85 + }, + { + "name": "girl/chest-control", + "order": 11, + "bone": "chest-control", + "x": 1, + "y": 1, + "limit": 500, + "inertia": 0.354, + "strength": 146.9, + "damping": 0.8938, + "mass": 2 + }, + { + "name": "girl/face-control", + "order": 7, + "bone": "face-control", + "x": 0.5, + "y": 0.5, + "limit": 1500, + "inertia": 0.1372, + "strength": 138.9, + "damping": 0.6372 + }, + { + "name": "girl/feathers-front", + "order": 10, + "bone": "feathers-front", + "rotate": 1, + "limit": 1500, + "inertia": 0.5, + "strength": 48.8, + "damping": 0.85 + }, + { + "name": "girl/feathers-front-top", + "order": 13, + "bone": "feathers-front-top", + "rotate": 1, + "limit": 1500, + "inertia": 0.5, + "strength": 48.8, + "damping": 0.85 + }, + { + "name": "girl/jabot", + "order": 12, + "bone": "jabot", + "rotate": 1, + "scaleX": 0.7011, + "limit": 1500, + "inertia": 0.2566, + "damping": 0.7965, + "mass": 1.36, + "windGlobal": true + } +], +"skins": [ + { + "name": "default", + "attachments": { + "arm-back-down": { + "arm-back-down": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 0.62552, 0, 1, 0, 0.30019, 0.75582, 0.67336, 0.80436 ], + "triangles": [ 5, 2, 3, 6, 3, 4, 0, 6, 4, 5, 1, 2, 1, 5, 6, 0, 1, 6, 5, 3, 6 ], + "vertices": [ 1, 34, 266.05, 30.04, 1, 1, 34, 226.94, -56.53, 1, 2, 5, 14.31, 488.57, 0.7907, 7, 0.93, -860.73, 0.2093, 2, 5, 73.73, 488.57, 0.7907, 7, 60.36, -860.73, 0.2093, 2, 5, 109.31, 488.57, 0.7907, 7, 95.93, -860.73, 0.2093, 2, 34, 192.84, -9.84, 0.7879, 5, 42.83, 332.87, 0.2121, 2, 34, 216.55, 18.35, 0.7879, 5, 78.28, 322.87, 0.2121 ], + "hull": 5, + "edges": [ 0, 2, 2, 4, 0, 8, 4, 6, 6, 8 ], + "width": 95, + "height": 206 + } + }, + "arm-back-up": { + "arm-back-up": { "x": -86.1, "y": -20.9, "rotation": -90, "width": 208, "height": 290 } + }, + "arm-front-down": { + "arm-front-down": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 0.43452, 0, 0.67692, 0, 1, 0, 0.31332, 0.74613, 0.71731, 0.75077 ], + "triangles": [ 1, 6, 0, 6, 7, 0, 6, 3, 7, 6, 1, 2, 0, 7, 5, 3, 4, 7, 7, 4, 5, 6, 2, 3 ], + "vertices": [ 1, 32, 227.27, 54.07, 1, 1, 32, 265.18, -27.55, 1, 2, 4, -107.35, 521.45, 0.6047, 6, -105.68, -832.87, 0.3953, 2, 4, -68.25, 521.45, 0.6047, 6, -66.58, -832.87, 0.3953, 2, 4, -46.43, 521.45, 0.6047, 6, -44.76, -832.87, 0.3953, 2, 4, -17.35, 521.45, 0.6047, 6, -15.68, -832.87, 0.3953, 3, 4, -79.16, 375.21, 0.15283, 32, 208.17, -22.94, 0.81603, 6, -77.48, -979.11, 0.03115, 3, 4, -42.8, 374.3, 0.2334, 32, 193.68, 10.42, 0.71976, 6, -41.12, -980.02, 0.04684 ], + "hull": 6, + "edges": [ 0, 2, 4, 6, 6, 8, 8, 10, 2, 4, 10, 0 ], + "width": 90, + "height": 196 + } + }, + "arm-front-up": { + "arm-front-up": { "x": 83.58, "y": 4.97, "rotation": 114.91, "width": 192, "height": 290 } + }, + "bench": { + "bench": { "x": 149.15, "y": 26.95, "width": 473, "height": 119 } + }, + "body-bottom": { + "body-bottom": { "x": 0.06, "y": -1.26, "rotation": -90, "width": 385, "height": 311 } + }, + "body-top": { + "body-top": { + "type": "mesh", + "uvs": [ 0.68503, 0.0173, 0.77124, 0.03199, 0.91531, 0.05656, 1, 0.43324, 1, 0.67192, 0.92419, 1, 0.7759, 1, 0.42918, 0.97744, 0.26456, 0.96673, 0.14336, 0.62093, 0, 0.2119, 0, 0.18595, 0.14242, 0.01727, 0.31495, 0.00606, 0.38463, 0.55715, 0.30121, 0.21217, 0.9283, 0.59001, 0.92255, 0.42573 ], + "triangles": [ 17, 1, 2, 3, 17, 2, 6, 16, 4, 16, 6, 14, 16, 14, 17, 16, 3, 4, 1, 17, 0, 0, 17, 15, 16, 17, 3, 0, 15, 13, 5, 6, 4, 8, 14, 7, 14, 6, 7, 8, 9, 14, 9, 15, 14, 9, 10, 15, 17, 14, 15, 15, 11, 12, 15, 12, 13, 15, 10, 11 ], + "vertices": [ 2, 10, 305.7, -37.39, 0.67811, 33, 42.16, 74.63, 0.32189, 2, 10, 300.82, -64.63, 0.4046, 33, 37.28, 47.39, 0.5954, 1, 33, 29.13, 1.86, 1, 2, 10, 167.61, -136.92, 0.7252, 33, -95.93, -24.9, 0.2748, 2, 10, 88.36, -136.92, 0.7252, 33, -175.17, -24.9, 0.2748, 1, 9, 121.56, -113.8, 1, 2, 31, -258.3, -211.49, 0.2636, 9, 121.56, -66.94, 0.7364, 2, 31, -250.81, -101.92, 0.3876, 9, 129.05, 42.62, 0.6124, 1, 9, 132.61, 94.64, 1, 2, 31, -132.44, -11.6, 0.458, 10, 105.29, 133.78, 0.542, 1, 31, 3.35, 33.7, 1, 1, 31, 11.97, 33.7, 1, 2, 31, 67.97, -11.31, 0.68, 10, 305.71, 134.07, 0.32, 1, 10, 309.43, 79.55, 1, 2, 31, -111.27, -87.84, 0.8168, 10, 126.47, 57.54, 0.1832, 1, 31, 3.26, -61.48, 1, 2, 10, 115.56, -114.26, 0.9535, 33, -147.98, -2.25, 0.0465, 2, 10, 170.1, -112.45, 0.7252, 33, -93.44, -0.43, 0.2748 ], + "hull": 14, + "edges": [ 4, 6, 6, 8, 8, 10, 10, 12, 20, 22, 22, 24, 16, 18, 18, 20, 12, 14, 14, 16, 2, 4, 24, 26, 0, 2, 26, 0 ], + "width": 316, + "height": 332 + } + }, + "chest": { + "chest": { + "type": "mesh", + "uvs": [ 0.45001, 0, 0.57525, 0.0237, 0.76703, 0.22276, 0.97238, 0.4359, 1, 0.66542, 1, 0.81592, 0.7799, 0.99414, 0.13228, 0.99919, 0, 0.20603, 0, 0.12601, 0.18781, 0, 0.34662, 0.79353, 0.63746, 0.78251, 0.85889, 0.71271, 0.61432, 0.54004, 0.49204, 0.35267, 0.31357, 0.55841, 0.81262, 0.47023, 0.23094, 0.33063, 0.3334, 0.8964, 0.65398, 0.89272, 0.87211, 0.81925, 0.17806, 0.67229 ], + "triangles": [ 20, 19, 11, 7, 19, 6, 16, 18, 15, 19, 22, 11, 8, 10, 18, 8, 9, 10, 7, 8, 22, 22, 8, 18, 7, 22, 19, 22, 18, 16, 22, 16, 11, 11, 16, 14, 20, 11, 12, 16, 15, 14, 11, 14, 12, 13, 17, 4, 18, 10, 0, 15, 0, 1, 15, 1, 2, 18, 0, 15, 17, 2, 3, 14, 15, 2, 17, 14, 2, 13, 4, 5, 21, 13, 5, 6, 20, 21, 6, 21, 5, 19, 20, 6, 17, 3, 4, 12, 14, 13, 12, 13, 21, 20, 12, 21, 14, 17, 13 ], + "vertices": [ 1, 10, 306.44, -25.48, 1, 2, 33, 37.38, 54.11, 0.1756, 10, 300.92, -57.91, 0.8244, 2, 33, -9, 4.44, 0.1756, 10, 254.54, -107.58, 0.8244, 3, 17, 69.23, -79, 0.20371, 33, -58.66, -48.75, 0.4198, 10, 204.88, -160.77, 0.37649, 3, 17, 15.78, -86.35, 0.14356, 33, -112.14, -55.9, 0.3282, 10, 151.4, -167.92, 0.52824, 2, 33, -147.21, -55.9, 0.3282, 10, 116.33, -167.92, 0.6718, 1, 10, 74.81, -110.91, 1, 2, 10, 73.63, 56.82, 0.1679, 31, -164.11, -88.56, 0.8321, 2, 10, 258.44, 91.08, 0.1679, 31, 20.7, -54.3, 0.8321, 2, 10, 277.08, 91.08, 0.1679, 31, 39.34, -54.3, 0.8321, 2, 10, 306.44, 42.44, 0.313, 31, 68.7, -102.94, 0.687, 3, 17, -14.71, 82.76, 0.21816, 10, 121.55, 1.3, 0.09484, 31, -116.19, -144.08, 0.687, 3, 17, -11.86, 7.45, 0.41027, 10, 124.12, -74.02, 0.26153, 31, -113.62, -219.4, 0.3282, 3, 17, 4.62, -49.85, 0.49165, 33, -123.16, -19.36, 0.1527, 10, 140.38, -131.38, 0.35565, 3, 17, 44.61, 13.65, 0.41027, 10, 180.61, -68.03, 0.26153, 31, -57.12, -213.41, 0.3282, 3, 17, 88.15, 45.49, 0.30258, 10, 224.27, -36.36, 0.36922, 31, -13.47, -181.74, 0.3282, 3, 17, 40.04, 91.53, 0.21816, 10, 176.33, 9.86, 0.09484, 31, -61.4, -135.52, 0.687, 3, 17, 61.07, -37.65, 0.486, 33, -66.66, -7.37, 0.1527, 10, 196.88, -119.39, 0.3613, 3, 17, 93.03, 113.13, 0.14098, 10, 229.41, 31.26, 0.17202, 31, -8.33, -114.12, 0.687, 3, 17, -38.69, 86.1, 0.18636, 10, 97.58, 4.73, 0.12664, 31, -140.16, -140.65, 0.687, 3, 17, -37.52, 3.07, 0.34873, 10, 98.44, -78.3, 0.32307, 31, -139.3, -223.68, 0.3282, 3, 17, -20.19, -53.36, 0.42304, 33, -147.98, -22.78, 0.1603, 10, 115.56, -134.8, 0.41666, 3, 17, 13.37, 126.52, 0.17681, 10, 149.8, 44.96, 0.13619, 31, -87.94, -100.42, 0.687 ], + "hull": 11, + "edges": [ 0, 20, 0, 2, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 2, 4, 4, 6 ], + "width": 259, + "height": 233 + } + }, + "cloud-back": { + "cloud-back": { "x": 34, "y": -35, "width": 504, "height": 412 } + }, + "cloud-front": { + "cloud-front": { + "type": "mesh", + "uvs": [ 0.31327, 1, 0, 0.6177, 0, 0.42025, 0.19412, 0.14966, 0.35888, 0, 0.74282, 0, 1, 0.29836, 1, 0.56651, 0.88846, 0.97605, 0.41478, 0.80054, 0.21765, 0.47631, 0.33975, 0.22279, 0.54864, 0.12772, 0.6678, 0.17403, 0.81785, 0.30323, 0.77666, 0.58114, 0.62747, 0.67312, 0.44331, 0.66744, 0.36329, 0.40562, 0.50892, 0.29396, 0.70487, 0.40205, 0.82079, 0.74203, 0.8914, 0.43487 ], + "triangles": [ 8, 16, 21, 21, 16, 15, 9, 16, 8, 9, 17, 16, 9, 10, 17, 17, 10, 18, 21, 15, 22, 17, 19, 16, 16, 19, 20, 16, 20, 15, 13, 19, 12, 19, 13, 20, 17, 18, 19, 15, 14, 22, 15, 20, 14, 10, 11, 18, 18, 11, 19, 20, 13, 14, 19, 11, 12, 8, 0, 9, 1, 10, 0, 0, 10, 9, 8, 21, 7, 21, 22, 7, 1, 2, 10, 22, 6, 7, 2, 3, 10, 10, 3, 11, 22, 14, 6, 13, 5, 14, 14, 5, 6, 11, 4, 12, 11, 3, 4, 13, 12, 5, 12, 4, 5 ], + "vertices": [ 1, 1, -190.62, -261, 1, 1, 1, -445, -73.68, 1, 1, 1, -445, 23.08, 1, 1, 1, -287.38, 155.67, 1, 1, 1, -153.59, 229, 1, 1, 1, 158.17, 229, 1, 1, 1, 367, 82.8, 1, 1, 1, 367, -48.59, 1, 1, 1, 276.43, -249.27, 1, 2, 1, -108.2, -163.26, 0.2626, 59, -108.2, -189.18, 0.7374, 2, 1, -268.27, -4.39, 0.2626, 59, -268.27, -30.31, 0.7374, 2, 1, -169.12, 119.83, 0.2626, 59, -169.12, 93.92, 0.7374, 2, 1, 0.5, 166.42, 0.2626, 59, 0.5, 140.5, 0.7374, 2, 1, 97.25, 143.72, 0.2626, 59, 97.25, 117.81, 0.7374, 2, 1, 219.09, 80.42, 0.2626, 59, 219.09, 54.5, 0.7374, 1, 59, 185.64, -81.67, 1, 1, 59, 64.51, -126.75, 1, 1, 59, -85.03, -123.96, 1, 1, 59, -150.01, 4.33, 1, 1, 59, -31.75, 59.04, 1, 1, 59, 127.35, 6.08, 1, 2, 1, 221.48, -134.59, 0.2626, 59, 221.48, -160.51, 0.7374, 2, 1, 278.82, 15.91, 0.2626, 59, 278.82, -10, 0.7374 ], + "hull": 9, + "edges": [ 2, 4, 6, 8, 8, 10, 12, 14, 14, 16, 4, 6, 0, 2, 16, 0, 10, 12 ], + "width": 812, + "height": 490 + } + }, + "collar": { + "collar": { "x": 318.94, "y": 22.08, "rotation": -90, "width": 118, "height": 65 } + }, + "glove-bottom-back": { + "glove-bottom-back": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 2, 7, 127.93, -931.73, 0.1628, 5, 141.31, 417.57, 0.8372, 2, 7, -0.07, -931.73, 0.1628, 5, 13.31, 417.57, 0.8372, 2, 7, -0.07, -829.73, 0.1628, 5, 13.31, 519.57, 0.8372, 2, 7, 127.93, -829.73, 0.1628, 5, 141.31, 519.57, 0.8372 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 128, + "height": 102 + } + }, + "glove-bottom-front": { + "glove-bottom-front": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 2, 6, 9.32, -909.87, 0.3023, 4, 7.65, 444.45, 0.6977, 2, 6, -108.68, -909.87, 0.3023, 4, -110.35, 444.45, 0.6977, 2, 6, -108.68, -788.87, 0.3023, 4, -110.35, 565.45, 0.6977, 2, 6, 9.32, -788.87, 0.3023, 4, 7.65, 565.45, 0.6977 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 118, + "height": 121 + } + }, + "hand-back": { + "hand-back": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 2, 7, 101.93, -888.73, 0.1628, 5, 115.31, 460.57, 0.8372, 2, 7, -47.07, -888.73, 0.1628, 5, -33.69, 460.57, 0.8372, 2, 7, -47.07, -771.73, 0.1628, 5, -33.69, 577.57, 0.8372, 2, 7, 101.93, -771.73, 0.1628, 5, 115.31, 577.57, 0.8372 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 149, + "height": 117 + } + }, + "hand-front": { + "hand-front": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 6, 43.32, -868.87, 0.3023, 4, 41.65, 485.45, 0.6977, 2, 6, -89.68, -868.87, 0.3023, 4, -91.35, 485.45, 0.6977, 2, 6, -89.68, -718.87, 0.3023, 4, -91.35, 635.45, 0.6977, 2, 6, 43.32, -718.87, 0.3023, 4, 41.65, 635.45, 0.6977 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 133, + "height": 150 + } + }, + "head-back": { + "head-back": { "x": 143.48, "y": -6.28, "rotation": -90, "width": 255, "height": 216 } + }, + "jabot": { + "jabot": { + "type": "mesh", + "uvs": [ 0, 0.00242, 0.68427, 0.0674, 0.78113, 0.19093, 0.92461, 0.37391, 1, 0.47007, 1, 0.77668, 0.68139, 0.9938, 0.25297, 0.99999, 0, 0.59156, 0.10822, 0.43911, 0.20325, 0.30524, 1.0E-5, 0.15397, 0.29926, 0.57598, 0.67862, 0.52015, 0.47435, 0.25963 ], + "triangles": [ 12, 13, 6, 7, 8, 12, 7, 12, 6, 13, 3, 4, 5, 13, 4, 6, 13, 5, 12, 8, 9, 12, 14, 13, 13, 2, 3, 9, 10, 12, 0, 10, 11, 1, 14, 0, 14, 10, 0, 2, 14, 1, 2, 13, 14, 12, 10, 14 ], + "vertices": [ 1, 10, 323.11, 83.08, 1, 1, 10, 314.14, -37.35, 1, 1, 10, 297.09, -54.4, 1, 2, 10, 271.84, -79.65, 0.3511, 19, 28.05, 69.71, 0.6489, 3, 10, 258.57, -92.92, 0.22821, 19, 43.89, 79.78, 0.57989, 17, 122.67, -10.95, 0.1919, 3, 10, 216.26, -92.92, 0.14314, 19, 85.19, 70.6, 0.50336, 17, 80.35, -11.11, 0.3535, 3, 19, 102.27, 9.36, 0.37012, 17, 50.18, 44.86, 0.20238, 31, -51.44, -182.23, 0.4275, 3, 19, 86.75, -64.43, 0.3751, 17, 49.04, 120.25, 0.2051, 31, -52.29, -106.82, 0.4198, 4, 10, 241.81, 83.08, 0.10381, 19, 22.07, -95.66, 0.36505, 17, 105.24, 164.99, 0.11134, 31, 4.07, -62.3, 0.4198, 2, 10, 262.84, 64.03, 0.3511, 19, 5.67, -72.51, 0.6489, 1, 10, 281.32, 47.31, 1, 1, 10, 302.19, 83.08, 1, 4, 10, 243.96, 30.41, 0.03577, 19, 31.4, -43.78, 0.43309, 17, 107.59, 112.33, 0.11134, 31, 6.22, -114.97, 0.4198, 4, 10, 251.66, -36.36, 0.0353, 19, 38.36, 23.07, 0.42734, 17, 115.54, 45.59, 0.10986, 31, 13.92, -181.74, 0.4275, 1, 10, 287.61, -0.41, 1 ], + "hull": 12, + "edges": [ 0, 22, 0, 2, 8, 10, 10, 12, 12, 14, 14, 16, 20, 22, 2, 4, 4, 6, 6, 8, 16, 18, 18, 20 ], + "width": 176, + "height": 138 + } + }, + "leg-back": { + "leg-back": { + "type": "mesh", + "uvs": [ 0.32178, 1.0E-5, 0.65435, 0.2781, 0.68868, 0.31943, 0.70599, 0.34212, 0.72097, 0.37811, 0.74825, 0.44366, 0.81512, 0.57229, 0.88933, 0.74052, 0.91935, 0.79172, 0.93814, 0.82344, 1, 0.92792, 1, 0.99738, 0.92956, 1, 0.89693, 1, 0.74794, 0.8868, 0.75056, 0.80978, 0.74352, 0.76967, 0.58619, 0.589, 0.53314, 0.47715, 0.51888, 0.42426, 0.49157, 0.38949, 0.38189, 0.33429, 0.00221, 0.25355, 0, 0, 0.61105, 0.38965, 0.82789, 0.78577, 0.84871, 0.8316, 0.67341, 0.63766 ], + "triangles": [ 10, 26, 9, 26, 10, 14, 10, 12, 13, 13, 14, 10, 11, 12, 10, 18, 19, 24, 5, 17, 18, 24, 4, 5, 5, 18, 24, 17, 5, 6, 27, 17, 6, 27, 6, 7, 16, 27, 7, 17, 27, 16, 25, 16, 7, 25, 7, 8, 15, 16, 25, 26, 25, 8, 26, 8, 9, 15, 25, 26, 14, 15, 26, 4, 24, 3, 3, 24, 2, 22, 23, 0, 21, 22, 0, 1, 21, 0, 20, 21, 1, 24, 20, 1, 2, 24, 1, 19, 20, 24 ], + "vertices": [ 1, 11, 6.11, 129.11, 1, 2, 11, 291.73, 79.64, 0.99946, 12, -78.35, 48.04, 5.4E-4, 2, 11, 328.42, 66.88, 0.80865, 12, -40.02, 54.36, 0.19135, 2, 11, 347.98, 59.31, 0.57491, 12, -19.23, 57.06, 0.42509, 2, 11, 374.22, 42.84, 0.29825, 12, 11.7, 55.13, 0.70175, 1, 12, 68.04, 51.63, 1, 1, 12, 180.76, 51.39, 1, 1, 12, 326.03, 44.49, 1, 2, 12, 371.46, 46.09, 0.83005, 13, -20.62, 46.6, 0.16995, 2, 12, 399.64, 47.17, 0.63671, 13, 7.58, 47, 0.36329, 1, 13, 100.44, 48.33, 1, 1, 13, 154.94, 28.9, 1, 1, 13, 144.61, -6.6, 1, 1, 13, 138.87, -22.71, 1, 2, 12, 418.59, -64, 0.15021, 13, 23.84, -64.6, 0.84979, 2, 12, 358.08, -42.62, 0.88261, 13, -36.14, -41.76, 0.11739, 1, 12, 325.19, -35.68, 1, 1, 12, 156.46, -66.9, 1, 2, 11, 359, -84.68, 0.05891, 12, 59.27, -64.15, 0.94109, 2, 11, 323.39, -57.69, 0.38892, 12, 15.09, -57.47, 0.61108, 2, 11, 293.12, -46.39, 0.86698, 12, -16.9, -62, 0.13302, 1, 11, 219.75, -52.23, 1, 1, 11, 28.71, -139.47, 1, 1, 11, -116.77, 13.65, 1, 1, 11, 338.83, -3.61, 1, 1, 12, 351.76, 2.12, 1, 2, 12, 391.43, 0.53, 0.59072, 13, -1.75, 0.58, 0.40928, 1, 12, 209.26, -36.17, 1 ], + "hull": 24, + "edges": [ 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30, 32, 32, 34, 40, 42, 42, 44, 44, 46, 38, 40, 0, 2, 2, 4, 34, 36, 36, 38, 8, 10, 14, 16, 10, 12, 12, 14, 46, 0, 16, 18, 18, 20, 4, 6, 6, 8 ], + "width": 524, + "height": 833 + } + }, + "leg-front": { + "leg-front": { + "type": "mesh", + "uvs": [ 0.2969, 2.9E-4, 0.42768, 0.05548, 0.59878, 0.15796, 0.6729, 0.22265, 0.68354, 0.26066, 0.69232, 0.29199, 0.6999, 0.31906, 0.70297, 0.35118, 0.7066, 0.38928, 0.71781, 0.50659, 0.74604, 0.58144, 0.79461, 0.71079, 0.82243, 0.74694, 0.84954, 0.78219, 0.87827, 0.81953, 0.93986, 0.89147, 0.96913, 0.90818, 1, 0.95735, 1, 1, 0.95733, 1, 0.84902, 0.98418, 0.74245, 0.97522, 0.69287, 0.89751, 0.70858, 0.8364, 0.71574, 0.80857, 0.70333, 0.77999, 0.54961, 0.5917, 0.50703, 0.39889, 0.46896, 0.33342, 0.29427, 0.28929, 0.2526, 0.31853, 1.0E-5, 0.27849, 0, 0, 0.60991, 0.31513, 0.78952, 0.80682, 0.79263, 0.83757, 0.84003, 0.80682 ], + "triangles": [ 13, 36, 34, 36, 13, 14, 35, 34, 36, 24, 34, 35, 23, 24, 35, 35, 22, 23, 21, 22, 35, 14, 35, 36, 15, 35, 14, 15, 20, 35, 21, 35, 20, 16, 20, 15, 19, 16, 17, 19, 20, 16, 18, 19, 17, 13, 34, 12, 33, 4, 5, 33, 5, 6, 26, 27, 8, 33, 7, 27, 6, 7, 33, 7, 8, 27, 9, 26, 8, 10, 26, 9, 25, 10, 11, 25, 11, 12, 26, 10, 25, 34, 25, 12, 24, 25, 34, 31, 32, 0, 29, 31, 0, 29, 0, 1, 28, 29, 1, 33, 2, 3, 33, 3, 4, 2, 28, 1, 30, 31, 29, 33, 28, 2, 27, 28, 33 ], + "vertices": [ 1, 14, 26.69, 123.29, 1, 1, 14, 121.98, 125.47, 1, 1, 14, 258.37, 107.11, 1, 2, 14, 325.3, 84.95, 0.7863, 15, -59.49, 60.64, 0.2137, 2, 14, 346.02, 61.65, 0.62278, 15, -28.38, 58.62, 0.37722, 2, 14, 363.09, 42.45, 0.37112, 15, -2.74, 56.95, 0.62888, 2, 14, 377.85, 25.86, 0.15366, 15, 19.42, 55.51, 0.84634, 2, 14, 392, 4.32, 0.08338, 15, 44.62, 50.13, 0.91662, 1, 15, 74.52, 43.75, 1, 1, 15, 166.57, 24.1, 1, 1, 15, 229.17, 24.62, 1, 1, 15, 337.29, 25.39, 1, 2, 15, 370.13, 34.43, 0.6412, 16, -21.35, 46.49, 0.3588, 2, 15, 402.13, 43.24, 0.49447, 16, 11.55, 42.08, 0.50553, 2, 15, 436.04, 52.57, 0.04576, 16, 46.4, 37.4, 0.95424, 2, 15, 502.5, 74.42, 0, 16, 116.12, 31.5, 1, 2, 15, 520.68, 88.77, 0, 16, 138.46, 37.59, 1, 2, 15, 564.06, 96.75, 0, 16, 181.5, 27.96, 1, 2, 15, 596.79, 87.08, 0, 16, 207.84, 6.25, 1, 1, 16, 190.3, -15.01, 1, 1, 16, 136.03, -60.96, 1, 2, 15, 530.63, -66.86, 0, 16, 86.72, -109.53, 1, 2, 15, 461.92, -79.96, 0.03259, 16, 18.37, -94.7, 0.96741, 2, 15, 417.92, -56.38, 0.32661, 16, -12.9, -55.78, 0.67339, 2, 15, 397.88, -45.63, 0.7066, 16, -27.14, -38.05, 0.2934, 2, 15, 373.68, -46.84, 0.97283, 16, -49.88, -29.69, 0.02717, 1, 15, 201.08, -99.4, 1, 2, 14, 299.64, -90.27, 0.24722, 15, 45.36, -82.07, 0.75278, 2, 14, 252.8, -56.31, 0.90138, 15, -11.83, -90.82, 0.09862, 1, 14, 136.94, -79.94, 1, 1, 14, 124.68, -113.43, 1, 1, 14, -33.65, -164.25, 1, 1, 14, -141.33, 30.79, 1, 2, 14, 325.44, 0.51, 0.49238, 15, -0.07, 0.65, 0.50762, 2, 15, 410.04, 0.47, 0.39999, 16, 2.09, -0.38, 0.60001, 1, 16, 22.35, -14.47, 1, 2, 15, 419.29, 31.76, 0.19906, 16, 22.85, 24.8, 0.80094 ], + "hull": 33, + "edges": [ 2, 4, 4, 6, 18, 20, 30, 32, 32, 34, 34, 36, 38, 40, 42, 44, 48, 50, 50, 52, 58, 60, 62, 64, 64, 0, 60, 62, 0, 2, 56, 58, 52, 54, 16, 18, 26, 28, 44, 46, 46, 48, 22, 24, 24, 26, 20, 22, 28, 30, 36, 38, 40, 42, 54, 56, 10, 12, 6, 8, 8, 10, 12, 14, 14, 16 ], + "width": 646, + "height": 800 + } + }, + "logo-brooch": { + "logo-brooch": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 10, 246.44, -26.92, 0.7273, 17, 110.29, 55.01, 0.2727, 2, 10, 246.44, 13.08, 0.7273, 17, 110.14, 95.01, 0.2727, 1, 10, 308.44, 13.08, 1, 1, 10, 308.44, -26.92, 1 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 40, + "height": 62 + } + }, + "neck": { + "neck": { "x": 64, "y": -0.01, "rotation": -90, "width": 97, "height": 141 } + }, + "rope-back": { + "rope-back": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0.95833, 0, 0.91667, 0, 0.875, 0, 0.83333, 0, 0.79167, 0, 0.75, 0, 0.70833, 0, 0.66667, 0, 0.625, 0, 0.58333, 0, 0.54167, 0, 0.5, 0, 0.45833, 0, 0.41667, 0, 0.375, 0, 0.33333, 0, 0.29167, 0, 0.25, 0, 0.20833, 0, 0.16667, 0, 0.125, 0, 0.08333, 0, 0.04167, 0, 0, 1, 0, 1, 0.04167, 1, 0.08333, 1, 0.125, 1, 0.16667, 1, 0.20833, 1, 0.25, 1, 0.29167, 1, 0.33333, 1, 0.375, 1, 0.41667, 1, 0.45833, 1, 0.5, 1, 0.54167, 1, 0.58333, 1, 0.625, 1, 0.66667, 1, 0.70833, 1, 0.75, 1, 0.79167, 1, 0.83333, 1, 0.875, 1, 0.91667, 1, 0.95833 ], + "triangles": [ 38, 13, 37, 12, 13, 38, 39, 12, 38, 11, 12, 39, 40, 11, 39, 10, 11, 40, 41, 10, 40, 9, 10, 41, 42, 9, 41, 8, 9, 42, 43, 8, 42, 7, 8, 43, 44, 7, 43, 6, 7, 44, 45, 6, 44, 5, 6, 45, 46, 5, 45, 4, 5, 46, 47, 4, 46, 3, 4, 47, 48, 3, 47, 2, 3, 48, 49, 2, 48, 1, 2, 49, 0, 1, 49, 24, 25, 26, 27, 24, 26, 23, 24, 27, 28, 23, 27, 22, 23, 28, 29, 22, 28, 21, 22, 29, 30, 21, 29, 20, 21, 30, 31, 20, 30, 19, 20, 31, 32, 19, 31, 18, 19, 32, 33, 18, 32, 17, 18, 33, 34, 17, 33, 16, 17, 34, 35, 16, 34, 15, 16, 35, 36, 15, 35, 14, 15, 36, 37, 14, 36, 13, 14, 37 ], + "vertices": [ 2, 7, 15.93, -1218.87, 0.06239, 5, 29.31, 130.43, 0.93761, 2, 7, -9.07, -1218.87, 0.06239, 5, 4.31, 130.43, 0.93761, 2, 7, -9.07, -1167.62, 0.06783, 5, 4.31, 181.68, 0.93217, 2, 7, -9.07, -1116.37, 0.07874, 5, 4.31, 232.93, 0.92126, 2, 7, -9.07, -1065.12, 0.0952, 5, 4.31, 284.18, 0.9048, 2, 7, -9.07, -1013.87, 0.11728, 5, 4.31, 335.43, 0.88272, 2, 7, -9.07, -962.62, 0.14499, 5, 4.31, 386.68, 0.85501, 2, 7, -9.07, -911.37, 0.17827, 5, 4.31, 437.93, 0.82173, 2, 7, -9.07, -860.12, 0.21693, 5, 4.31, 489.18, 0.78307, 2, 7, -9.07, -808.87, 0.2606, 5, 4.31, 540.43, 0.73939, 2, 7, -9.07, -757.62, 0.30875, 5, 4.31, 591.68, 0.69125, 2, 7, -9.07, -706.37, 0.36064, 5, 4.31, 642.93, 0.63936, 2, 7, -9.07, -655.12, 0.41536, 5, 4.31, 694.18, 0.58464, 2, 7, -9.07, -603.87, 0.4719, 5, 4.31, 745.43, 0.5281, 2, 7, -9.07, -552.62, 0.52914, 5, 4.31, 796.68, 0.47086, 2, 7, -9.07, -501.37, 0.58596, 5, 4.31, 847.93, 0.41404, 2, 7, -9.07, -450.12, 0.64132, 5, 4.31, 899.18, 0.35868, 2, 7, -9.07, -398.87, 0.69428, 5, 4.31, 950.43, 0.30572, 2, 7, -9.07, -347.62, 0.74413, 5, 4.31, 1001.68, 0.25586, 2, 7, -9.07, -296.37, 0.7904, 5, 4.31, 1052.93, 0.2096, 2, 7, -9.07, -245.12, 0.83286, 5, 4.31, 1104.18, 0.16714, 2, 7, -9.07, -193.87, 0.87161, 5, 4.31, 1155.43, 0.12839, 2, 7, -9.07, -142.62, 0.90701, 5, 4.31, 1206.68, 0.09299, 2, 7, -9.07, -91.37, 0.93965, 5, 4.31, 1257.93, 0.06036, 2, 7, -9.07, -40.12, 0.97033, 5, 4.31, 1309.18, 0.02967, 1, 7, -9.07, 11.13, 1, 1, 7, 15.93, 11.13, 1, 2, 7, 15.93, -40.12, 0.97033, 5, 29.31, 1309.18, 0.02967, 2, 7, 15.93, -91.37, 0.93965, 5, 29.31, 1257.93, 0.06036, 2, 7, 15.93, -142.62, 0.90701, 5, 29.31, 1206.68, 0.09299, 2, 7, 15.93, -193.87, 0.87161, 5, 29.31, 1155.43, 0.12839, 2, 7, 15.93, -245.12, 0.83286, 5, 29.31, 1104.18, 0.16714, 2, 7, 15.93, -296.37, 0.7904, 5, 29.31, 1052.93, 0.2096, 2, 7, 15.93, -347.62, 0.74413, 5, 29.31, 1001.68, 0.25586, 2, 7, 15.93, -398.87, 0.69428, 5, 29.31, 950.43, 0.30572, 2, 7, 15.93, -450.12, 0.64132, 5, 29.31, 899.18, 0.35868, 2, 7, 15.93, -501.37, 0.58596, 5, 29.31, 847.93, 0.41404, 2, 7, 15.93, -552.62, 0.52914, 5, 29.31, 796.68, 0.47086, 2, 7, 15.93, -603.87, 0.4719, 5, 29.31, 745.43, 0.5281, 2, 7, 15.93, -655.12, 0.41536, 5, 29.31, 694.18, 0.58464, 2, 7, 15.93, -706.37, 0.36064, 5, 29.31, 642.93, 0.63936, 2, 7, 15.93, -757.62, 0.30875, 5, 29.31, 591.68, 0.69125, 2, 7, 15.93, -808.87, 0.2606, 5, 29.31, 540.43, 0.73939, 2, 7, 15.93, -860.12, 0.21693, 5, 29.31, 489.18, 0.78307, 2, 7, 15.93, -911.37, 0.17827, 5, 29.31, 437.93, 0.82173, 2, 7, 15.93, -962.62, 0.14499, 5, 29.31, 386.68, 0.85501, 2, 7, 15.93, -1013.87, 0.11728, 5, 29.31, 335.43, 0.88272, 2, 7, 15.93, -1065.12, 0.0952, 5, 29.31, 284.18, 0.9048, 2, 7, 15.93, -1116.37, 0.07874, 5, 29.31, 232.93, 0.92126, 2, 7, 15.93, -1167.62, 0.06783, 5, 29.31, 181.68, 0.93217 ], + "hull": 50, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 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, 74, 76, 76, 78, 78, 80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94, 96, 96, 98, 98, 0 ], + "width": 25, + "height": 1230 + } + }, + "rope-front": { + "rope-front": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0.95833, 0, 0.91667, 0, 0.875, 0, 0.83333, 0, 0.79167, 0, 0.75, 0, 0.70833, 0, 0.66667, 0, 0.625, 0, 0.58333, 0, 0.54167, 0, 0.5, 0, 0.45833, 0, 0.41667, 0, 0.375, 0, 0.33333, 0, 0.29167, 0, 0.25, 0, 0.20833, 0, 0.16667, 0, 0.125, 0, 0.08333, 0, 0.04167, 0, 0, 1, 0, 1, 0.04167, 1, 0.08333, 1, 0.125, 1, 0.16667, 1, 0.20833, 1, 0.25, 1, 0.29167, 1, 0.33333, 1, 0.375, 1, 0.41667, 1, 0.45833, 1, 0.5, 1, 0.54167, 1, 0.58333, 1, 0.625, 1, 0.66667, 1, 0.70833, 1, 0.75, 1, 0.79167, 1, 0.83333, 1, 0.875, 1, 0.91667, 1, 0.95833 ], + "triangles": [ 0, 1, 49, 1, 2, 49, 49, 2, 48, 2, 3, 48, 48, 3, 47, 3, 4, 47, 47, 4, 46, 4, 5, 46, 46, 5, 45, 5, 6, 45, 45, 6, 44, 6, 7, 44, 44, 7, 43, 7, 8, 43, 43, 8, 42, 8, 9, 42, 42, 9, 41, 9, 10, 41, 41, 10, 40, 10, 11, 40, 40, 11, 39, 11, 12, 39, 39, 12, 38, 12, 13, 38, 38, 13, 37, 13, 14, 37, 37, 14, 36, 14, 15, 36, 36, 15, 35, 15, 16, 35, 35, 16, 34, 16, 17, 34, 34, 17, 33, 17, 18, 33, 33, 18, 32, 18, 19, 32, 32, 19, 31, 19, 20, 31, 31, 20, 30, 20, 21, 30, 30, 21, 29, 21, 22, 29, 29, 22, 28, 22, 23, 28, 28, 23, 27, 23, 24, 27, 27, 24, 26, 24, 25, 26 ], + "vertices": [ 2, 6, 15.32, -1218.87, 0.01425, 4, 13.65, 135.45, 0.98575, 2, 6, -9.68, -1218.87, 0.01425, 4, -11.35, 135.45, 0.98575, 2, 6, -9.68, -1167.62, 0.03549, 4, -11.35, 186.7, 0.96451, 2, 6, -9.68, -1116.37, 0.05791, 4, -11.35, 237.95, 0.94209, 2, 6, -9.68, -1065.12, 0.08257, 4, -11.35, 289.2, 0.91743, 2, 6, -9.68, -1013.87, 0.11037, 4, -11.35, 340.45, 0.88963, 2, 6, -9.68, -962.62, 0.142, 4, -11.35, 391.7, 0.858, 2, 6, -9.68, -911.37, 0.17784, 4, -11.35, 442.95, 0.82216, 2, 6, -9.68, -860.12, 0.21806, 4, -11.35, 494.2, 0.78194, 2, 6, -9.68, -808.87, 0.26251, 4, -11.35, 545.45, 0.73749, 2, 6, -9.68, -757.62, 0.31083, 4, -11.35, 596.7, 0.68917, 2, 6, -9.68, -706.37, 0.36243, 4, -11.35, 647.95, 0.63757, 2, 6, -9.68, -655.12, 0.41654, 4, -11.35, 699.2, 0.58346, 2, 6, -9.68, -603.87, 0.47225, 4, -11.35, 750.45, 0.52776, 2, 6, -9.68, -552.62, 0.52855, 4, -11.35, 801.7, 0.47145, 2, 6, -9.68, -501.37, 0.58444, 4, -11.35, 852.95, 0.41556, 2, 6, -9.68, -450.12, 0.63896, 4, -11.35, 904.2, 0.36104, 2, 6, -9.68, -398.87, 0.69127, 4, -11.35, 955.45, 0.30873, 2, 6, -9.68, -347.62, 0.74069, 4, -11.35, 1006.7, 0.25931, 2, 6, -9.68, -296.37, 0.78679, 4, -11.35, 1057.95, 0.21321, 2, 6, -9.68, -245.12, 0.82936, 4, -11.35, 1109.2, 0.17064, 2, 6, -9.68, -193.87, 0.86847, 4, -11.35, 1160.45, 0.13153, 2, 6, -9.68, -142.62, 0.90445, 4, -11.35, 1211.7, 0.09555, 2, 6, -9.68, -91.37, 0.93784, 4, -11.35, 1262.95, 0.06216, 2, 6, -9.68, -40.12, 0.9694, 4, -11.35, 1314.2, 0.0306, 1, 6, -9.68, 11.13, 1, 1, 6, 15.32, 11.13, 1, 2, 6, 15.32, -40.12, 0.9694, 4, 13.65, 1314.2, 0.0306, 2, 6, 15.32, -91.37, 0.93784, 4, 13.65, 1262.95, 0.06216, 2, 6, 15.32, -142.62, 0.90445, 4, 13.65, 1211.7, 0.09555, 2, 6, 15.32, -193.87, 0.86847, 4, 13.65, 1160.45, 0.13153, 2, 6, 15.32, -245.12, 0.82936, 4, 13.65, 1109.2, 0.17064, 2, 6, 15.32, -296.37, 0.78679, 4, 13.65, 1057.95, 0.21321, 2, 6, 15.32, -347.62, 0.74069, 4, 13.65, 1006.7, 0.25931, 2, 6, 15.32, -398.87, 0.69127, 4, 13.65, 955.45, 0.30873, 2, 6, 15.32, -450.12, 0.63896, 4, 13.65, 904.2, 0.36104, 2, 6, 15.32, -501.37, 0.58444, 4, 13.65, 852.95, 0.41556, 2, 6, 15.32, -552.62, 0.52855, 4, 13.65, 801.7, 0.47145, 2, 6, 15.32, -603.87, 0.47225, 4, 13.65, 750.45, 0.52776, 2, 6, 15.32, -655.12, 0.41654, 4, 13.65, 699.2, 0.58346, 2, 6, 15.32, -706.37, 0.36243, 4, 13.65, 647.95, 0.63757, 2, 6, 15.32, -757.62, 0.31083, 4, 13.65, 596.7, 0.68917, 2, 6, 15.32, -808.87, 0.26251, 4, 13.65, 545.45, 0.73749, 2, 6, 15.32, -860.12, 0.21806, 4, 13.65, 494.2, 0.78194, 2, 6, 15.32, -911.37, 0.17784, 4, 13.65, 442.95, 0.82216, 2, 6, 15.32, -962.62, 0.142, 4, 13.65, 391.7, 0.858, 2, 6, 15.32, -1013.87, 0.11037, 4, 13.65, 340.45, 0.88963, 2, 6, 15.32, -1065.12, 0.08257, 4, 13.65, 289.2, 0.91743, 2, 6, 15.32, -1116.37, 0.05791, 4, 13.65, 237.95, 0.94209, 2, 6, 15.32, -1167.62, 0.03549, 4, 13.65, 186.7, 0.96451 ], + "hull": 50, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 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, 74, 76, 76, 78, 78, 80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94, 96, 96, 98, 98, 0 ], + "width": 25, + "height": 1230 + } + }, + "rope-front-bottom": { + "rope-front-bottom": { "x": 6.65, "y": 90.45, "width": 106, "height": 162 } + }, + "skirt": { + "skirt": { + "type": "mesh", + "uvs": [ 0.46879, 0.00497, 0.6193, 0.00865, 0.73168, 0.0729, 0.79086, 0.14366, 0.84028, 0.20275, 0.88824, 0.26009, 0.94354, 0.36305, 0.99934, 0.46693, 0.99902, 0.53745, 0.95967, 0.62431, 0.73749, 0.83501, 0.67118, 0.86255, 0.64669, 0.83712, 0.63777, 0.79457, 0.54456, 0.88007, 0.41826, 0.85692, 0.33176, 0.67054, 0.38298, 0.45193, 0.32025, 0.393, 0.25971, 0.50948, 0.25592, 0.54358, 0.29136, 0.69557, 0.26023, 0.76971, 0.23714, 0.78393, 0.24583, 0.96708, 0.21631, 1, 0.18626, 1, 0.13297, 0.98375, 0.0482, 0.9579, 0, 0.74426, 0, 0.71238, 0.02405, 0.63249, 0.05524, 0.52888, 0.08731, 0.42235, 0.14673, 0.31698, 0.23977, 0.15198, 0.37537, 0.00268, 0.78833, 0.34934, 0.65072, 0.38132, 0.57259, 0.40578, 0.43328, 0.39355, 0.25324, 0.41895, 0.07649, 0.66731, 0.10759, 0.5469, 0.14767, 0.71528, 0.16981, 0.55631, 0.17312, 0.35376, 0.82186, 0.47041, 0.69302, 0.54288, 0.59275, 0.58024 ], + "triangles": [ 21, 23, 20, 17, 40, 15, 16, 17, 15, 23, 45, 20, 20, 45, 19, 45, 46, 41, 19, 45, 41, 19, 41, 18, 17, 18, 40, 18, 41, 35, 18, 36, 40, 41, 46, 35, 11, 12, 13, 10, 47, 9, 10, 48, 47, 47, 6, 9, 8, 9, 7, 48, 37, 47, 7, 9, 6, 47, 5, 6, 47, 37, 5, 37, 4, 5, 37, 3, 4, 10, 11, 13, 25, 26, 24, 24, 26, 23, 26, 27, 23, 27, 44, 23, 27, 28, 44, 28, 29, 42, 28, 42, 44, 31, 42, 30, 23, 21, 22, 23, 44, 45, 42, 29, 30, 42, 43, 44, 44, 43, 45, 31, 32, 42, 42, 32, 43, 45, 43, 46, 32, 33, 43, 46, 33, 34, 46, 43, 33, 46, 34, 35, 13, 48, 10, 37, 38, 3, 14, 15, 49, 49, 40, 39, 39, 1, 38, 1, 39, 0, 39, 40, 0, 40, 36, 0, 18, 35, 36, 38, 1, 2, 3, 38, 2, 49, 39, 38, 49, 38, 48, 48, 38, 37, 14, 49, 13, 13, 49, 48, 40, 49, 15 ], + "vertices": [ 2, 9, 138.5, 15.05, 0.4884, 31, -241.35, -129.5, 0.5116, 1, 9, 136.23, -150.36, 1, 3, 9, 96.66, -273.87, 0.814, 40, -398.02, 529.23, 0, 41, -147.06, 12.37, 0.186, 3, 9, 53.07, -338.91, 0.59714, 40, -373.76, 603.67, 0, 41, -78.06, 49.37, 0.40286, 3, 9, 16.67, -393.22, 0.41605, 40, -353.5, 665.83, 0, 41, -20.44, 80.26, 0.58395, 2, 9, -18.65, -445.93, 0.2403, 41, 35.48, 110.24, 0.7597, 2, 9, -82.08, -506.71, 0.2093, 41, 120, 134.17, 0.7907, 1, 41, 205.28, 158.32, 1, 2, 9, -189.51, -567.68, 0.04571, 41, 243.48, 137.63, 0.95429, 2, 9, -243.01, -524.44, 0.18, 41, 270.45, 74.34, 0.82, 2, 9, -372.8, -280.26, 0.54183, 41, 270.54, -202.19, 0.45817, 2, 9, -389.77, -207.39, 0.4651, 41, 251.35, -274.5, 0.5349, 2, 9, -374.1, -180.47, 0.4651, 41, 224.88, -290.93, 0.5349, 2, 9, -347.89, -170.66, 0.4651, 41, 197.14, -287.3, 0.5349, 3, 9, -400.56, -68.23, 0.46933, 41, 195.61, -402.46, 0.25937, 4, 242.12, -226.67, 0.2713, 4, 9, -386.3, 70.57, 0.56245, 40, 160.39, 329.06, 3.0E-5, 41, 117.91, -518.37, 0.16622, 4, 103.31, -212.42, 0.2713, 3, 40, 75.75, 206.36, 0.00607, 41, -28.08, -548.47, 0.12573, 4, 8.25, -97.6, 0.8682, 1, 4, 64.54, 37.06, 1, 1, 4, -4.4, 73.36, 1, 2, 40, 1.8, 103.19, 0.1318, 4, -70.93, 1.61, 0.8682, 1, 4, -75.1, -19.39, 1, 2, 40, 102.65, 167.82, 0.4651, 4, -36.15, -113.02, 0.5349, 2, 40, 155.91, 147.31, 0.64377, 4, -70.37, -158.69, 0.35623, 2, 40, 171.24, 125.28, 0.51563, 4, -95.74, -167.45, 0.48437, 2, 40, 277.21, 165.15, 0.77714, 4, -86.18, -280.27, 0.22286, 2, 40, 305.54, 139.44, 0.88571, 4, -118.63, -300.55, 0.11429, 2, 40, 314.52, 107.65, 0.80857, 4, -151.66, -300.55, 0.19143, 2, 40, 320.81, 48.57, 0.78571, 4, -210.22, -290.54, 0.21429, 1, 40, 330.82, -45.4, 1, 1, 40, 218.57, -132.16, 1, 1, 40, 199.67, -137.5, 1, 3, 9, -248.05, 503.81, 0.02228, 40, 145.13, -125.45, 0.95682, 4, -329.92, -74.16, 0.0209, 3, 9, -184.23, 469.54, 0.08011, 40, 74.39, -109.81, 0.86977, 4, -295.65, -10.34, 0.05012, 3, 9, -118.6, 434.29, 0.20512, 40, 1.66, -93.74, 0.70568, 4, -260.41, 55.28, 0.0892, 3, 9, -53.7, 368.99, 0.40948, 40, -78.56, -48.54, 0.4572, 4, -195.1, 120.19, 0.13332, 3, 9, 47.94, 266.73, 0.66886, 40, -204.17, 22.23, 0.15284, 4, -92.84, 221.83, 0.1783, 1, 9, 139.91, 117.71, 1, 2, 9, -73.63, -336.14, 0.3798, 41, 32.53, -12.51, 0.6202, 4, 9, -93.33, -184.9, 0.7038, 40, -191, 495.26, 0, 41, -21, -155.32, 0.24191, 31, -473.19, -329.44, 0.05429, 4, 9, -108.4, -99.03, 0.70715, 40, -153.16, 416.72, 1.1E-4, 41, -47.98, -238.22, 0.17845, 31, -488.26, -243.58, 0.11429, 2, 4, 119.82, 73.02, 0.8217, 31, -480.72, -90.48, 0.1783, 1, 4, -78.04, 57.38, 1, 2, 40, 150.1, -64.16, 0.7752, 4, -272.3, -95.61, 0.2248, 2, 40, 69.43, -51.42, 0.6899, 4, -238.11, -21.44, 0.3101, 2, 40, 157.27, 19.15, 0.7752, 4, -194.07, -125.16, 0.2248, 3, 9, -201.12, 343.62, 4.5E-4, 40, 56.42, 15.95, 0.68945, 4, -169.73, -27.24, 0.3101, 3, 9, -76.35, 339.99, 0.06162, 40, -64.64, -14.47, 0.64378, 4, -166.1, 97.53, 0.2946, 2, 9, -148.21, -372.98, 0.2403, 41, 115.68, -14.95, 0.7597, 2, 9, -192.85, -231.39, 0.5891, 41, 88.69, -160.94, 0.4109, 3, 9, -215.87, -121.19, 0.5659, 40, -55.76, 467.26, 1.0E-5, 41, 57.33, -269.06, 0.43409 ], + "hull": 37, + "edges": [ 2, 4, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 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, 56, 58, 58, 60, 70, 72, 64, 66, 60, 62, 62, 64, 52, 54, 54, 56, 66, 68, 68, 70, 86, 92, 10, 12, 12, 14, 30, 80, 2, 0, 0, 72, 4, 6, 6, 8, 8, 10 ], + "width": 1099, + "height": 616 + } + }, + "sock-bow": { + "sock-bow": { + "type": "mesh", + "uvs": [ 0.99999, 0.72, 0.75258, 0.92781, 0.22969, 1, 1.0E-5, 0.92563, 1.0E-5, 0.78642, 0.06114, 0.10062, 0.48481, 0.07, 0.87771, 1.0E-5, 0.21914, 0.65955, 0.54384, 0.47361, 0.92125, 0.55017, 0.11372, 0.57861, 0.42577, 0.77111, 0.57969, 0.72736, 0.45951, 0.1958, 0.54595, 0.17611 ], + "triangles": [ 15, 6, 7, 14, 5, 6, 9, 15, 10, 11, 14, 9, 14, 6, 15, 9, 14, 15, 15, 7, 10, 11, 5, 14, 8, 11, 9, 13, 9, 10, 12, 8, 9, 13, 12, 9, 0, 10, 7, 1, 13, 10, 11, 4, 5, 4, 11, 8, 2, 3, 4, 0, 1, 10, 2, 8, 12, 2, 4, 8, 1, 2, 12, 1, 12, 13 ], + "vertices": [ 1, 39, 34.06, 38.19, 1, 1, 39, 49.83, 16.99, 1, 1, 39, 53.81, -26.61, 1, 1, 39, 47.08, -45.41, 1, 1, 39, 35.95, -44.96, 1, 2, 39, -18.66, -37.63, 0.5344, 15, 231.35, -77.03, 0.4656, 1, 15, 238.97, -42.61, 1, 2, 39, -23.91, 30.42, 0.5344, 15, 242.84, -9.75, 0.4656, 2, 39, 26.56, -26.36, 0.5344, 15, 277.95, -77.12, 0.4656, 1, 15, 271.32, -47.06, 1, 2, 39, 20.22, 32.22, 0.5344, 15, 286.07, -18.76, 0.4656, 2, 39, 19.73, -34.84, 0.5344, 15, 269.26, -83.68, 0.4656, 2, 39, 36.18, -9.6, 0.5344, 15, 291.37, -63.2, 0.4656, 2, 39, 33.21, 3.31, 0.5344, 15, 291.63, -49.96, 0.4656, 1, 15, 248.02, -47.48, 1, 1, 15, 248.54, -40.15, 1 ], + "hull": 8, + "edges": [ 0, 14, 6, 8, 8, 10, 4, 6, 0, 2, 2, 4, 10, 12, 12, 14 ], + "width": 83, + "height": 80 + } + }, + "spine-logo-body": { + "spine-logo-body": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 0, 1, 3 ], + "vertices": [ 2, 31, -248.3, -203.3, 0.6279, 33, -274.1, 54.1, 0.3721, 2, 31, -248.3, -171.3, 0.6977, 33, -274.1, 86.1, 0.3023, 2, 31, -169.3, -171.3, 0.6977, 33, -195.1, 86.1, 0.3023, 2, 31, -169.3, -203.3, 0.6279, 33, -195.1, 54.1, 0.3721 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 32, + "height": 79 + } + }, + "underskirt": { + "underskirt": { + "type": "mesh", + "uvs": [ 0.61384, 0.00326, 0.86014, 0.1566, 1, 0.41744, 0.99999, 0.63264, 0.91366, 0.67712, 0.71449, 0.81522, 0.48265, 0.87782, 0.37222, 0.75816, 0.31568, 0.69151, 0.33041, 0.38409, 0.3203, 0.38107, 0.28115, 0.91727, 0.22206, 1, 0.13682, 0.99971, 0.05161, 0.92594, 0, 0.71479, 0, 0.68836, 0.09431, 0.39249, 0.29714, 0.10495, 0.42184, 0.00353 ], + "triangles": [ 5, 1, 4, 5, 0, 1, 3, 4, 2, 2, 4, 1, 12, 13, 11, 17, 11, 13, 16, 13, 14, 16, 14, 15, 17, 13, 16, 10, 11, 17, 6, 7, 0, 6, 0, 5, 19, 0, 9, 8, 9, 7, 0, 7, 9, 17, 18, 10, 19, 9, 18, 9, 10, 18 ], + "vertices": [ 3, 9, 59.71, -144.35, 0.82348, 42, -622.06, 414.02, 1.0E-5, 43, -424.46, -118.81, 0.17652, 2, 9, -27.7, -418.23, 0.20974, 43, -218.8, 82.08, 0.79026, 2, 9, -176.38, -573.76, 0.00244, 43, -14.54, 149.69, 0.99756, 1, 43, 93.78, 92.15, 1, 2, 9, -324.39, -477.75, 0.00233, 43, 71.15, -4.52, 0.99767, 2, 9, -403.12, -256.27, 0.35855, 43, 36.78, -237.06, 0.64145, 3, 9, -438.79, 1.54, 0.73381, 42, -102.67, 409.16, 0.0028, 43, -52.63, -481.48, 0.26339, 3, 9, -370.59, 124.33, 0.82181, 42, -134.93, 272.44, 0.02156, 43, -170.47, -557.93, 0.15663, 3, 9, -332.6, 187.21, 0.83983, 42, -154.39, 201.61, 0.03404, 43, -233.51, -595.65, 0.12614, 3, 9, -157.37, 170.82, 0.72848, 42, -327.47, 169.74, 0.2419, 43, -380.58, -498.98, 0.02962, 3, 9, -155.65, 182.06, 0.65493, 42, -326.07, 158.45, 0.32779, 43, -387.37, -508.1, 0.01728, 2, 9, -461.28, 225.6, 0.0394, 42, -20.11, 199.65, 0.9606, 2, 9, -508.44, 291.31, 0.01441, 42, 43.13, 149.23, 0.98559, 2, 9, -508.27, 386.1, 5.6E-4, 42, 68.74, 57.97, 0.99944, 1, 42, 54.04, -44.65, 1, 2, 9, -345.87, 538.24, 0.02475, 42, -46.18, -132.6, 0.97525, 2, 9, -330.8, 538.24, 0.02806, 42, -60.68, -136.69, 0.97194, 2, 9, -162.16, 433.37, 0.22852, 42, -251.48, -81.62, 0.77148, 2, 9, 1.74, 207.82, 0.78318, 42, -470.53, 90.88, 0.21682, 3, 9, 59.55, 69.15, 0.97304, 42, -563.86, 208.61, 0.02695, 43, -524.47, -307.44, 1.0E-5 ], + "hull": 20, + "edges": [ 0, 38, 0, 2, 2, 4, 4, 6, 8, 10, 10, 12, 12, 14, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30, 32, 32, 34, 34, 36, 36, 38, 14, 16, 16, 18, 18, 20, 6, 8 ], + "width": 1112, + "height": 570 + } + }, + "underskirt-back": { + "underskirt-back": { + "type": "mesh", + "uvs": [ 0.8116, 0, 1, 0.3776, 1, 0.45388, 0.98647, 0.56624, 0.92179, 0.61762, 0.8759, 0.61039, 0.87506, 0.61851, 0.72906, 0.8252, 0.48046, 0.90197, 0.37375, 0.98138, 0.17375, 1, 0.14891, 1, 0, 0.76838, 0, 0.7307, 0.01937, 0.5828, 0.09779, 0.29851, 0.26066, 0.09077, 0.63845, 0 ], + "triangles": [ 8, 17, 7, 6, 7, 5, 7, 17, 0, 5, 7, 0, 3, 4, 2, 4, 1, 2, 5, 1, 4, 1, 5, 0, 16, 9, 10, 10, 14, 15, 14, 11, 13, 10, 11, 14, 10, 15, 16, 9, 16, 8, 11, 12, 13, 8, 16, 17 ], + "vertices": [ 2, 9, -29.44, -358.72, 0.4574, 43, -245.18, 28.7, 0.5426, 1, 43, -6.75, 133.1, 1, 1, 43, 22.09, 117.78, 1, 1, 43, 57.69, 82.29, 1, 2, 42, -372.61, 831.26, 1.1E-4, 43, 44.25, 10.1, 0.99989, 2, 42, -362.08, 782.6, 0.00633, 43, 18.21, -32.33, 0.99367, 2, 42, -358.49, 782.66, 0.00746, 43, 20.85, -34.77, 0.99254, 2, 42, -230.37, 654.55, 0.14266, 43, 24.81, -215.91, 0.85734, 2, 42, -125.55, 404.39, 0.58607, 43, -72.45, -469.09, 0.41393, 2, 42, -61.42, 302.42, 0.78309, 43, -96.64, -587.1, 0.21691, 2, 42, 5.13, 96.14, 0.98087, 43, -191.2, -782.14, 0.01913, 2, 42, 12.44, 70.26, 0.9887, 43, -203.82, -805.89, 0.0113, 1, 42, -39.11, -111.89, 1, 1, 42, -54.63, -116.28, 1, 1, 42, -121.25, -113.3, 1, 2, 9, -157.2, 414.33, 0.6279, 42, -261.43, -64.65, 0.3721, 3, 9, -68.29, 237.94, 0.6279, 42, -394.95, 80.92, 0.33514, 43, -490.74, -516.48, 0.03696, 3, 9, -29.44, -171.2, 0.6279, 42, -543.57, 464.1, 0.0647, 43, -333.14, -136.91, 0.3074 ], + "hull": 18, + "edges": [ 0, 34, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30, 32, 32, 34, 14, 16 ], + "width": 1083, + "height": 428 + } + }, + "wing-back": { + "wing-back": { + "type": "mesh", + "uvs": [ 0.27992, 1, 0.41993, 0.8511, 0.63506, 0.69103, 0.71019, 0.49935, 0.7819, 0.3709, 1, 0.06855, 1, 0, 0.83312, 0, 0.50871, 0.27604, 0.42334, 0.38473, 0.29016, 0.46773, 0.23894, 0.57049, 0, 0.70289, 0, 1 ], + "triangles": [ 3, 10, 9, 3, 9, 4, 9, 8, 4, 4, 8, 5, 8, 7, 5, 7, 6, 5, 0, 13, 1, 13, 12, 1, 12, 11, 1, 1, 11, 2, 2, 11, 3, 3, 11, 10 ], + "vertices": [ 1, 37, -58.79, -72.37, 1, 1, 37, 46.56, -55.93, 1, 2, 37, 174.1, -56.94, 0.68025, 38, -28.45, -51.1, 0.31975, 2, 37, 286.48, -5.39, 0.4003, 38, 93.74, -32.27, 0.5997, 2, 37, 366.51, 22.98, 0.17872, 38, 178.48, -26.89, 0.82128, 1, 38, 384.52, -30.9, 1, 1, 38, 424.63, -15.07, 1, 1, 38, 402.32, 41.43, 1, 2, 37, 353.46, 138.21, 0.10957, 38, 197.47, 87.52, 0.89043, 2, 37, 280.29, 121.34, 0.25682, 38, 122.47, 91.32, 0.74318, 2, 37, 209.37, 128.12, 0.46071, 38, 56.11, 117.24, 0.53929, 2, 37, 146.7, 103.65, 0.71584, 38, -10.86, 110.85, 0.28416, 2, 37, 27.71, 122.12, 0.99997, 38, -120.26, 161.17, 3.0E-5, 1, 37, -120.71, 8.55, 1 ], + "hull": 14, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 0, 26 ], + "width": 364, + "height": 629 + } + }, + "wing-front": { + "wing-front": { + "type": "mesh", + "uvs": [ 0, 0, 0.02331, 0, 0.22961, 0.21519, 0.35084, 0.26796, 0.43003, 0.30243, 0.488, 0.32767, 0.53152, 0.4064, 0.57005, 0.47608, 0.62939, 0.54328, 1, 0.68105, 0.99999, 0.99998, 0.617, 0.99221, 0.44034, 0.85621, 0.38946, 0.74627, 0.35759, 0.67741, 0.3699, 0.6309, 0.30589, 0.58118, 0.22551, 0.51873, 0.16197, 0.39023, 0.08039, 0.22526, 0.00685, 0.07654 ], + "triangles": [ 5, 15, 4, 16, 4, 15, 16, 3, 4, 16, 17, 3, 3, 18, 2, 3, 17, 18, 18, 19, 2, 2, 19, 1, 19, 20, 1, 20, 0, 1, 10, 11, 9, 11, 8, 9, 11, 12, 8, 12, 13, 8, 14, 15, 13, 7, 13, 15, 7, 8, 13, 15, 6, 7, 15, 5, 6 ], + "vertices": [ 1, 36, 423.69, -49.6, 1, 1, 36, 408.05, -57.92, 1, 1, 36, 206.97, -13.75, 1, 2, 35, 555.33, -8.25, 0.10655, 36, 110.26, -28.12, 0.89345, 2, 35, 494.8, -28.62, 0.21311, 36, 47.09, -37.51, 0.78689, 2, 35, 450.49, -43.54, 0.49546, 36, 0.85, -44.38, 0.50454, 2, 35, 394.32, -25.6, 0.76147, 36, -51.28, -16.82, 0.23853, 2, 35, 344.61, -9.71, 0.92422, 36, -97.42, 7.57, 0.07578, 2, 35, 283.41, -4.82, 0.9928, 36, -156.8, 23.18, 0.0072, 1, 35, 9.16, -111.67, 1, 1, 35, -113, 43.82, 1, 1, 35, 118.85, 219.86, 1, 2, 35, 276.52, 236.51, 0.96534, 36, -121.05, 261.95, 0.03466, 2, 35, 349.03, 206.81, 0.92167, 36, -54.9, 219.92, 0.07833, 2, 35, 394.46, 188.2, 0.916, 36, -13.47, 193.6, 0.084, 2, 35, 404.91, 159.74, 0.7786, 36, -8.19, 163.75, 0.2214, 2, 35, 462.21, 165.55, 0.4504, 36, 49.24, 159.37, 0.5496, 2, 35, 534.17, 172.86, 0.29838, 36, 121.35, 153.88, 0.70162, 2, 35, 621.37, 140.04, 0.14825, 36, 201.4, 106.21, 0.85175, 1, 36, 304.17, 45.02, 1, 1, 36, 396.81, -10.14, 1 ], + "hull": 21, + "edges": [ 0, 2, 14, 16, 22, 24, 28, 30, 40, 0, 34, 36, 36, 38, 4, 6, 30, 32, 32, 34, 6, 8, 8, 10, 10, 12, 12, 14, 30, 10, 24, 26, 26, 28, 26, 14, 18, 20, 16, 18, 20, 22, 38, 40, 2, 4 ], + "width": 760, + "height": 620 + } + }, + "face/fringe-front/fringe-middle-back": { + "fringe-middle-back": { + "type": "mesh", + "uvs": [ 0.32752, 0, 0.86964, 0.29818, 1, 0.59486, 1, 1, 0.28701, 1, 0.30763, 0.65487, 0, 0.25321, 0, 0 ], + "triangles": [ 4, 5, 3, 5, 2, 3, 5, 1, 2, 5, 6, 1, 6, 0, 1, 6, 7, 0 ], + "vertices": [ 1, 20, 208.48, -106.96, 1, 2, 20, 169.72, -151.96, 0.6589, 28, 110.56, -69.29, 0.3411, 2, 20, 131.15, -162.78, 0.3535, 30, 34.61, 37.03, 0.6465, 2, 20, 78.48, -162.78, 0.3535, 30, 87.28, 37.03, 0.6465, 3, 20, 78.48, -103.6, 0.1164, 30, 87.28, -22.15, 0.6465, 28, 19.32, -20.93, 0.2371, 3, 20, 123.35, -105.31, 0.1164, 30, 42.41, -20.44, 0.6465, 28, 64.19, -22.64, 0.2371, 2, 20, 175.56, -79.78, 0.6589, 28, 116.4, 2.89, 0.3411, 1, 20, 208.48, -79.78, 1 ], + "hull": 8, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 0, 14 ], + "width": 83, + "height": 130 + } + }, + "face/fringe-front/fringe-middle-front": { + "fringe-middle-front": { + "type": "mesh", + "uvs": [ 1, 1, 0.75, 1, 0.5, 1, 0.25, 1, 0, 1, 0, 0.66667, 0, 0.33333, 0, 0, 0.5, 0, 1, 0, 1, 0.33333, 1, 0.66667, 0.58576, 0.6538, 0.52144, 0.32047 ], + "triangles": [ 1, 11, 0, 2, 12, 1, 1, 12, 11, 2, 3, 12, 12, 3, 5, 3, 4, 5, 12, 10, 11, 5, 13, 12, 5, 6, 13, 12, 13, 10, 6, 8, 13, 10, 8, 9, 6, 7, 8, 10, 13, 8 ], + "vertices": [ 3, 20, 80.48, -129.78, 0.0853, 30, 85.28, 4.03, 0.303, 28, 21.32, -47.11, 0.6117, 2, 30, 85.28, -33.47, 0.303, 28, 21.32, -9.61, 0.697, 2, 29, 90.56, 82.9, 0.3636, 28, 21.32, 27.89, 0.6364, 2, 29, 90.56, 45.4, 0.3636, 28, 21.32, 65.39, 0.6364, 2, 29, 90.56, 7.9, 0.3636, 28, 21.32, 102.89, 0.6364, 2, 29, 48.89, 7.9, 0.3636, 28, 62.99, 102.89, 0.6364, 2, 20, 163.81, 20.22, 0.3566, 28, 104.66, 102.89, 0.6434, 1, 20, 205.48, 20.22, 1, 1, 20, 205.48, -54.78, 1, 1, 20, 205.48, -129.78, 1, 2, 20, 163.81, -129.78, 0.3178, 28, 104.66, -47.11, 0.6822, 3, 20, 122.15, -129.78, 0.0853, 30, 43.61, 4.03, 0.303, 28, 62.99, -47.11, 0.6117, 2, 29, 47.28, 95.77, 0.3636, 28, 64.6, 15.03, 0.6364, 2, 20, 165.42, -57.99, 0.3566, 28, 106.26, 24.67, 0.6434 ], + "hull": 12, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 18, 20, 20, 22, 22, 0, 14, 16, 16, 18, 20, 16 ], + "width": 150, + "height": 125 + } + }, + "face/fringe-front/fringe-side-front": { + "fringe-side-front": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0.8, 0, 0.6, 0, 0.4, 0, 0.2, 0, 0, 1, 0, 1, 0.2, 1, 0.4, 1, 0.6, 1, 0.8 ], + "triangles": [ 3, 4, 9, 8, 5, 7, 5, 6, 7, 4, 5, 8, 9, 4, 8, 0, 1, 11, 1, 2, 11, 11, 2, 10, 2, 3, 10, 10, 3, 9 ], + "vertices": [ 1, 29, 217.56, 17.9, 1, 1, 29, 217.56, -48.1, 1, 2, 29, 171.16, -48.1, 0.82503, 28, -59.28, 158.89, 0.17497, 2, 29, 124.76, -48.1, 0.60616, 28, -12.88, 158.89, 0.39384, 3, 29, 78.36, -48.1, 0.3251, 20, 92.68, 76.22, 0.1478, 28, 33.52, 158.89, 0.5271, 2, 20, 139.08, 76.22, 0.1705, 28, 79.92, 158.89, 0.8295, 2, 20, 185.48, 76.22, 0.4031, 28, 126.32, 158.89, 0.5969, 2, 20, 185.48, 10.22, 0.4031, 28, 126.32, 92.89, 0.5969, 2, 20, 139.08, 10.22, 0.1705, 28, 79.92, 92.89, 0.8295, 3, 29, 78.36, 17.9, 0.3251, 20, 92.68, 10.22, 0.1478, 28, 33.52, 92.89, 0.5271, 2, 29, 124.76, 17.9, 0.60616, 28, -12.88, 92.89, 0.39384, 2, 29, 171.16, 17.9, 0.82503, 28, -59.28, 92.89, 0.17497 ], + "hull": 12, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 0 ], + "width": 66, + "height": 232 + } + }, + "face/ear": { + "ear": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 2, 20, 20.48, 52.22, 0.3101, 28, -38.68, 134.89, 0.6899, 2, 28, -38.68, 184.89, 0.7287, 22, -114.77, -50.15, 0.2713, 2, 28, 31.32, 184.89, 0.7287, 22, -44.77, -50.15, 0.2713, 2, 20, 90.48, 52.22, 0.3101, 28, 31.32, 134.89, 0.6899 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 50, + "height": 70 + } + }, + "face/eye-back-shadow": { + "eye-back-shadow": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 51, -20.35, -15.78, 0.2749, 49, -3.33, -18.17, 0.7251, 2, 51, -20.35, 19.22, 0.1085, 49, -3.33, 16.83, 0.8915, 2, 51, 3.65, 19.22, 0.69582, 49, 20.67, 16.83, 0.30418, 2, 51, 3.65, -15.78, 0.91085, 49, 20.67, -18.17, 0.08915 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 35, + "height": 24 + } + }, + "face/eye-front-shadow": { + "eye-front-shadow": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 47, -34.76, -19.78, 0.1604, 45, -11.68, -24.94, 0.8396, 2, 47, -34.76, 39.22, 0.03854, 45, -11.68, 34.06, 0.96146, 2, 47, 1.24, 39.22, 0.96, 45, 24.32, 34.06, 0.04, 2, 47, 1.24, -19.78, 0.92478, 45, 24.32, -24.94, 0.07522 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 59, + "height": 36 + } + }, + "face/eye-reflex-back": { + "eye-reflex-back": { "x": -1, "y": 6.42, "rotation": -90, "width": 19, "height": 17 } + }, + "face/eye-reflex-front": { + "eye-reflex-front": { "x": -2.07, "y": 7.22, "rotation": -90, "width": 25, "height": 18 } + }, + "face/eye-white-back": { + "eye-white-back": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 1, 52, -1.77, -14.73, 1, 1, 52, -1.77, 17.27, 1, 1, 51, 3.65, 19.22, 1, 2, 49, 20.67, -15.17, 0.03731, 51, 3.65, -12.78, 0.96269 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 32, + "height": 40 + } + }, + "face/eye-white-front": { + "eye-white-front": { + "type": "mesh", + "uvs": [ 0.98492, 0.7288, 0.74399, 0.97841, 0.09394, 0.97675, 0, 0.61321, 0.44029, 0.01082, 0.98133, 0.03613 ], + "triangles": [ 0, 1, 4, 1, 3, 4, 1, 2, 3, 0, 4, 5 ], + "vertices": [ 2, 45, -10.01, -24.09, 0.90792, 48, 9.81, -32.94, 0.09208, 1, 48, -0.92, -19.45, 1, 1, 48, -0.85, 16.95, 1, 3, 45, -5.04, 31.06, 0.13374, 47, -28.13, 36.22, 0.27714, 48, 14.78, 22.22, 0.58912, 1, 47, -2.23, 11.56, 1, 1, 47, -3.31, -18.74, 1 ], + "hull": 6, + "edges": [ 0, 10, 0, 2, 2, 4, 4, 6, 8, 10, 6, 8 ], + "width": 56, + "height": 43 + } + }, + "face/eyelashes-down-back": { + "eyelashes-down-back": { "x": -0.77, "y": -0.73, "rotation": -90, "width": 28, "height": 14 } + }, + "face/eyelashes-down-front": { + "eyelashes-down-front": { "x": -2.35, "y": 0.72, "rotation": -90, "width": 37, "height": 15 } + }, + "face/eyelashes-top-back": { + "eyelashes-top-back": { + "type": "mesh", + "uvs": [ 0.53449, 0.0112, 0.80224, 0.23436, 1, 0.50028, 0.89272, 0.90854, 0.67501, 0.92236, 0.35422, 0.73425, 0.24884, 0.95236, 0.02061, 0.96391, 0.02196, 0.59454, 0.24865, 0.01679 ], + "triangles": [ 7, 8, 6, 3, 1, 2, 5, 0, 4, 4, 1, 3, 4, 0, 1, 8, 9, 5, 5, 9, 0, 6, 8, 5 ], + "vertices": [ 1, 51, 9.38, -2.84, 1, 2, 51, 4.02, -14.88, 0.86286, 49, 21.04, -17.27, 0.13714, 2, 51, -2.36, -23.78, 0.5814, 49, 14.66, -26.17, 0.4186, 2, 51, -12.16, -18.96, 0.5814, 49, 4.86, -21.34, 0.4186, 2, 51, -12.49, -9.16, 0.6434, 49, 4.53, -11.54, 0.3566, 1, 51, -7.98, 5.28, 1, 2, 51, -13.21, 10.02, 0.6047, 49, 3.81, 7.63, 0.3953, 2, 51, -13.49, 20.29, 0.5814, 49, 3.53, 17.9, 0.4186, 2, 51, -4.62, 20.23, 0.5814, 49, 12.4, 17.84, 0.4186, 1, 51, 9.24, 10.03, 1 ], + "hull": 10, + "edges": [ 0, 18, 0, 2, 4, 6, 14, 16, 16, 18, 12, 14, 6, 8, 8, 10, 10, 12, 2, 4 ], + "width": 45, + "height": 24 + } + }, + "face/eyelashes-top-front": { + "eyelashes-top-front": { + "type": "mesh", + "uvs": [ 0, 0.74724, 0.51172, 0, 0.61319, 0, 0.99001, 0.18532, 0.99016, 0.28688, 0.83893, 0.5606, 0.6312, 0.2977, 0.48808, 0.44992, 0.18971, 1, 0.09689, 1, 0, 0.86051 ], + "triangles": [ 4, 5, 3, 7, 0, 1, 7, 1, 6, 1, 2, 6, 5, 6, 3, 6, 2, 3, 0, 8, 9, 9, 10, 0, 7, 8, 0 ], + "vertices": [ 1, 45, -1.31, 42.06, 1, 1, 47, 6.24, 9.35, 1, 1, 47, 6.24, 1.84, 1, 2, 45, 21.73, -31.2, 0.2713, 47, -1.36, -26.05, 0.7287, 2, 45, 17.56, -31.21, 0.2713, 47, -5.52, -26.06, 0.7287, 2, 45, 6.34, -20.02, 0.34, 47, -16.75, -14.87, 0.66, 1, 47, -5.97, 0.51, 1, 2, 45, 10.88, 5.94, 0.23429, 47, -12.21, 11.1, 0.76571, 1, 45, -11.68, 28.02, 1, 1, 45, -11.68, 34.89, 1, 1, 45, -5.96, 42.06, 1 ], + "hull": 11, + "edges": [ 0, 20, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20 ], + "width": 74, + "height": 41 + } + }, + "face/face": { + "face": { + "type": "mesh", + "uvs": [ 0.84841, 0, 0.99605, 0.18591, 0.99597, 0.82505, 0.75638, 1, 0.56116, 1, 0.28151, 0.91236, 0.02486, 0.65319, 0.25928, 0.18329, 0.83782, 0, 0.31251, 0.58794, 0.2902, 0.34407, 0.75589, 0.2771, 0.94411, 0.34407, 0.92878, 0.62458, 0.66107, 0.87982, 0.7811, 0.68326 ], + "triangles": [ 4, 14, 3, 3, 14, 2, 4, 5, 14, 5, 9, 14, 5, 6, 9, 14, 15, 2, 14, 9, 15, 15, 13, 2, 13, 12, 2, 2, 12, 1, 15, 9, 13, 6, 10, 9, 6, 7, 10, 9, 11, 13, 13, 11, 12, 9, 10, 11, 12, 11, 1, 10, 7, 11, 11, 8, 1, 8, 0, 1, 11, 7, 8 ], + "vertices": [ 1, 20, 201.48, -112.61, 1, 1, 20, 153.89, -146.86, 1, 2, 20, -9.73, -146.84, 0.2016, 28, -68.89, -64.18, 0.7984, 1, 28, -113.68, -8.59, 1, 1, 28, -113.68, 36.7, 1, 2, 20, -32.08, 18.91, 0.2481, 28, -91.24, 101.58, 0.7519, 2, 20, 34.26, 78.46, 0.3488, 28, -24.89, 161.12, 0.6512, 1, 20, 154.56, 24.07, 1, 1, 20, 201.48, -110.15, 1, 1, 28, -8.19, 94.39, 1, 1, 28, 54.24, 99.56, 1, 1, 28, 71.38, -8.48, 1, 2, 20, 113.4, -134.81, 0.2403, 28, 54.24, -52.14, 0.7597, 2, 20, 41.59, -131.25, 0.2403, 28, -17.57, -48.59, 0.7597, 1, 28, -82.91, 13.52, 1, 1, 21, 0.89, 2.3, 1 ], + "hull": 9, + "edges": [ 0, 16, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 18, 26 ], + "width": 232, + "height": 256 + } + }, + "face/fringe-side-back": { + "fringe-side-back": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0.8, 0, 0.6, 0, 0.4, 0, 0.2, 0, 0, 1, 0, 1, 0.2, 1, 0.4, 1, 0.6, 1, 0.8 ], + "triangles": [ 10, 3, 9, 3, 4, 9, 9, 4, 8, 8, 5, 7, 5, 6, 7, 4, 5, 8, 0, 1, 11, 1, 2, 11, 11, 2, 10, 2, 3, 10 ], + "vertices": [ 1, 30, 219.28, 49.03, 1, 1, 30, 219.28, -18.97, 1, 2, 30, 172.48, -18.97, 0.78148, 20, -6.72, -106.78, 0.21852, 2, 30, 125.68, -18.97, 0.54452, 20, 40.08, -106.78, 0.45548, 2, 30, 78.88, -18.97, 0.28148, 20, 86.88, -106.78, 0.71852, 1, 20, 133.68, -106.78, 1, 1, 20, 180.48, -106.78, 1, 1, 20, 180.48, -174.78, 1, 1, 20, 133.68, -174.78, 1, 2, 30, 78.88, 49.03, 0.28148, 20, 86.88, -174.78, 0.71852, 2, 30, 125.68, 49.03, 0.54452, 20, 40.08, -174.78, 0.45548, 2, 30, 172.48, 49.03, 0.78148, 20, -6.72, -174.78, 0.21852 ], + "hull": 12, + "edges": [ 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 0 ], + "width": 68, + "height": 234 + } + }, + "face/hair-hat-shadow": { + "hair-hat-shadow": { "x": 198.48, "y": 40.22, "rotation": -90, "width": 224, "height": 102 } + }, + "face/mouth": { + "mouth": { "x": 4.02, "y": -0.92, "rotation": -90, "width": 56, "height": 16 } + }, + "face/nose": { + "nose": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 1, 21, -13.2, -1.48, 1, 2, 28, -46.68, -3.11, 0.4, 21, -13.2, 13.52, 0.6, 2, 28, -29.68, -3.11, 0.4, 21, 3.8, 13.52, 0.6, 1, 21, 3.8, -1.48, 1 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 15, + "height": 17 + } + }, + "face/nose-highlight": { + "nose-highlight": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 2, 28, -33.68, -11.11, 0.124, 21, -0.2, 5.52, 0.876, 2, 28, -33.68, -1.11, 0.124, 21, -0.2, 15.52, 0.876, 2, 28, -22.68, -1.11, 0.124, 21, 10.8, 15.52, 0.876, 2, 28, -22.68, -11.11, 0.124, 21, 10.8, 5.52, 0.876 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 10, + "height": 11 + } + }, + "face/nose-shadow": { + "nose-shadow": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 1, 21, -15.2, -5.48, 1, 2, 28, -48.68, -4.11, 0.6047, 21, -15.2, 12.52, 0.3953, 2, 28, -28.68, -4.11, 0.6047, 21, 4.8, 12.52, 0.3953, 1, 21, 4.8, -5.48, 1 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 18, + "height": 20 + } + }, + "face/pupil-back": { + "pupil-back": { "x": -2.5, "y": 1.42, "rotation": -90, "width": 25, "height": 36 } + }, + "face/pupil-front": { + "pupil-front": { "x": -0.07, "y": 1.72, "rotation": -90, "width": 30, "height": 44 } + }, + "hair-back/hair-back-1": { + "hair-back-1": { + "type": "mesh", + "uvs": [ 1, 0.05206, 0.78167, 0.17387, 0.70445, 0.29745, 0.65078, 0.39485, 0.49669, 0.47826, 0.30981, 0.57942, 0.46147, 0.61966, 0.65876, 0.71313, 0.30967, 0.78419, 0.48938, 0.84645, 0.47689, 0.91323, 0.30103, 1, 0.21344, 1, 0.10045, 0.96739, 0.0798, 0.89237, 0.04833, 0.77797, 0, 0.60231, 0, 0.55114, 0.36021, 0.41385, 0.44814, 0.36733, 0.56438, 0.25145, 0.68422, 0.13617, 0.82577, 0, 1, 1.0E-5 ], + "triangles": [ 10, 11, 14, 14, 11, 12, 12, 13, 14, 5, 17, 18, 4, 19, 3, 3, 19, 2, 19, 20, 2, 18, 19, 4, 5, 18, 4, 14, 8, 10, 10, 8, 9, 14, 15, 8, 8, 15, 6, 15, 5, 6, 15, 16, 5, 16, 17, 5, 8, 6, 7, 0, 22, 23, 22, 0, 21, 0, 1, 21, 2, 20, 1, 20, 21, 1 ], + "vertices": [ 1, 20, 193.6, 53.22, 1, 1, 20, 100.3, 125.49, 1, 2, 20, 5.63, 151.05, 0.5115, 26, 123.22, -101.53, 0.4885, 2, 20, -68.98, 168.82, 0.3588, 26, 197.83, -119.3, 0.6412, 2, 20, -132.86, 219.82, 0.3053, 26, 261.72, -170.3, 0.6947, 3, 20, -210.35, 281.68, 0.26425, 26, 339.21, -232.16, 0.61722, 27, -129.44, -232.16, 0.11853, 3, 20, -241.18, 231.47, 0.22919, 26, 370.03, -181.96, 0.54443, 27, -98.61, -181.96, 0.22638, 3, 20, -312.77, 166.17, 0.2009, 26, 441.63, -116.65, 0.50653, 27, -27.02, -116.65, 0.29257, 3, 20, -367.21, 281.72, 0.18235, 26, 496.06, -232.2, 0.47614, 27, 27.42, -232.2, 0.3415, 3, 20, -414.9, 222.24, 0.21741, 26, 543.75, -172.72, 0.57649, 27, 75.11, -172.72, 0.2061, 3, 20, -466.05, 226.37, 0.23495, 26, 594.91, -176.85, 0.4504, 27, 126.26, -176.85, 0.31465, 3, 20, -532.52, 284.58, 0.23495, 26, 661.38, -235.06, 0.4504, 27, 192.73, -235.06, 0.31465, 3, 20, -532.52, 313.57, 0.23495, 26, 661.38, -264.05, 0.4504, 27, 192.73, -264.05, 0.31465, 3, 20, -507.54, 350.97, 0.23495, 26, 636.39, -301.46, 0.4504, 27, 167.75, -301.46, 0.31465, 3, 20, -450.07, 357.81, 0.23495, 26, 578.93, -308.29, 0.4504, 27, 110.28, -308.29, 0.31465, 3, 20, -362.45, 368.22, 0.23506, 26, 491.3, -318.71, 0.51948, 27, 22.66, -318.71, 0.24546, 3, 20, -227.89, 384.22, 0.25098, 26, 356.75, -334.7, 0.57166, 27, -111.9, -334.7, 0.17736, 3, 20, -188.7, 384.22, 0.27537, 26, 317.55, -334.7, 0.63085, 27, -151.1, -334.7, 0.09378, 2, 20, -83.53, 264.99, 0.3053, 26, 212.38, -215.47, 0.6947, 2, 20, -47.89, 235.89, 0.3588, 26, 176.75, -186.37, 0.6412, 2, 20, 40.87, 197.41, 0.49123, 26, 87.99, -147.89, 0.50877, 2, 20, 129.18, 157.75, 0.68581, 26, -0.32, -108.23, 0.31419, 1, 20, 233.48, 110.89, 1, 1, 20, 233.47, 53.22, 1 ], + "hull": 24, + "edges": [ 0, 2, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 32, 34, 34, 36, 36, 38, 44, 46, 30, 32, 30, 12, 26, 28, 28, 30, 6, 8, 8, 10, 4, 6, 38, 40, 2, 4, 46, 0, 40, 42, 42, 44 ], + "width": 331, + "height": 766 + } + }, + "hair-back/hair-back-2": { + "hair-back-2": { + "type": "mesh", + "uvs": [ 0.89086, 0, 0.99848, 0, 0.96651, 0.15477, 0.94381, 0.26466, 0.92222, 0.36914, 0.89845, 0.48424, 0.57735, 0.62302, 0.73413, 0.63077, 0.9883, 0.70379, 0.86085, 0.84916, 0.74336, 0.98316, 0.59619, 1, 0.37348, 1, 0.10983, 0.83684, 1.0E-5, 0.76887, 0, 0.66185, 0.06689, 0.57957, 0.28324, 0.47594, 0.49583, 0.37411, 0.59097, 0.27636, 0.69109, 0.15073, 0.80033, 0.01367, 0.54528, 0.76481 ], + "triangles": [ 22, 7, 8, 14, 15, 22, 13, 14, 22, 9, 22, 8, 9, 13, 22, 9, 12, 13, 9, 11, 12, 10, 11, 9, 4, 19, 3, 18, 19, 4, 5, 18, 4, 17, 18, 5, 6, 17, 5, 16, 17, 6, 15, 16, 6, 22, 15, 6, 22, 6, 7, 19, 20, 3, 3, 20, 2, 1, 21, 0, 2, 21, 1, 20, 21, 2 ], + "vertices": [ 1, 20, 157.48, 123.05, 1, 1, 20, 157.48, 101.53, 1, 2, 20, 47.29, 107.92, 0.70089, 26, 81.57, -58.4, 0.29911, 2, 20, -30.96, 112.46, 0.4885, 26, 159.82, -62.94, 0.5115, 2, 20, -105.35, 116.78, 0.33608, 26, 234.21, -67.26, 0.66392, 2, 20, -187.3, 121.53, 0.1832, 26, 316.15, -72.01, 0.8168, 3, 20, -286.11, 185.75, 0.1756, 26, 414.96, -136.23, 0.74597, 27, -53.68, -136.23, 0.07843, 3, 20, -291.63, 154.4, 0.1756, 26, 420.49, -104.88, 0.63052, 27, -48.16, -104.88, 0.19388, 3, 20, -343.62, 103.56, 0.1756, 26, 472.48, -54.04, 0.45922, 27, 3.83, -54.04, 0.36518, 3, 20, -447.12, 129.05, 0.1756, 26, 575.98, -79.53, 0.24092, 27, 107.33, -79.53, 0.58348, 2, 20, -542.53, 152.55, 0.1756, 27, 202.74, -103.03, 0.8244, 2, 20, -554.52, 181.98, 0.1756, 27, 214.73, -132.46, 0.8244, 2, 20, -554.52, 226.52, 0.1756, 27, 214.73, -177.01, 0.8244, 3, 20, -438.35, 279.26, 0.1756, 26, 567.2, -229.74, 0.24092, 27, 98.56, -229.74, 0.58348, 3, 20, -389.96, 301.22, 0.1756, 26, 518.81, -251.7, 0.45922, 27, 50.17, -251.7, 0.36518, 3, 20, -313.75, 301.22, 0.1756, 26, 442.61, -251.7, 0.63052, 27, -26.04, -251.7, 0.19388, 3, 20, -255.17, 287.84, 0.1756, 26, 384.03, -238.32, 0.74597, 27, -84.62, -238.32, 0.07843, 2, 20, -181.39, 244.57, 0.1832, 26, 310.24, -195.05, 0.8168, 2, 20, -108.88, 202.06, 0.33608, 26, 237.74, -152.54, 0.66392, 2, 20, -39.29, 183.03, 0.4885, 26, 168.15, -133.51, 0.5115, 2, 20, 50.16, 163, 0.6489, 26, 78.7, -113.48, 0.3511, 1, 20, 147.75, 141.16, 1, 2, 20, -387.07, 192.17, 0.1756, 27, 47.28, -142.65, 0.8244 ], + "hull": 22, + "edges": [ 0, 42, 0, 2, 10, 12, 12, 14, 14, 16, 20, 22, 22, 24, 28, 30, 30, 32, 36, 38, 6, 8, 8, 10, 32, 34, 34, 36, 24, 26, 26, 28, 16, 18, 18, 20, 38, 40, 40, 42, 2, 4, 4, 6 ], + "width": 200, + "height": 712 + } + }, + "hair-back/hair-back-3": { + "hair-back-3": { + "type": "mesh", + "uvs": [ 0.84591, 0.08889, 0.82372, 0.26566, 0.80438, 0.41975, 0.94221, 0.62567, 1, 0.81672, 0.70929, 0.99918, 0.46458, 0.99803, 0.23662, 0.83671, 0, 0.66926, 0, 0.51704, 0.21223, 0.38901, 0.3832, 0.26202, 0.39154, 0.00106, 0.78531, 0.00114 ], + "triangles": [ 4, 5, 7, 5, 6, 7, 4, 7, 3, 7, 8, 3, 8, 2, 3, 2, 8, 9, 2, 9, 10, 10, 11, 2, 2, 11, 1, 1, 11, 0, 0, 12, 13, 0, 11, 12 ], + "vertices": [ 1, 20, 43.92, 49.03, 1, 3, 20, -74.51, 52.89, 0.49873, 26, 203.37, -3.37, 0.44236, 27, -265.28, -3.37, 0.05891, 3, 20, -177.75, 56.26, 0.3969, 26, 306.6, -6.74, 0.30443, 27, -162.04, -6.74, 0.29867, 3, 20, -315.72, 32.28, 0.1145, 26, 444.58, 17.24, 0.16959, 27, -24.07, 17.24, 0.71591, 2, 20, -443.72, 22.22, 0.1145, 27, 103.93, 27.3, 0.8855, 2, 20, -565.97, 72.8, 0.1145, 27, 226.18, -23.29, 0.8855, 2, 20, -565.2, 115.38, 0.1145, 27, 225.41, -65.87, 0.8855, 3, 20, -457.12, 155.05, 0.1145, 26, 585.97, -105.53, 0.04756, 27, 117.32, -105.53, 0.83794, 3, 20, -344.93, 196.22, 0.1145, 26, 473.78, -146.7, 0.53505, 27, 5.13, -146.7, 0.35045, 3, 20, -242.93, 196.22, 0.1145, 26, 371.79, -146.7, 0.63528, 27, -96.86, -146.7, 0.25022, 3, 20, -157.16, 159.29, 0.30166, 26, 286.01, -109.77, 0.5576, 27, -182.63, -109.77, 0.14074, 3, 20, -72.07, 129.55, 0.49024, 26, 200.93, -80.03, 0.47767, 27, -267.72, -80.03, 0.03208, 1, 20, 102.77, 128.09, 1, 1, 20, 102.72, 59.58, 1 ], + "hull": 14, + "edges": [ 0, 26, 6, 8, 8, 10, 10, 12, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 12, 14, 14, 16, 14, 6, 16, 4, 6, 4, 0, 2, 2, 4 ], + "width": 174, + "height": 670 + } + }, + "hair-back/hair-back-4": { + "hair-back-4": { + "type": "mesh", + "uvs": [ 0.84401, 0.30705, 0.95315, 0.49123, 0.9783, 0.6272, 1, 0.74452, 0.91116, 0.87667, 0.91728, 1, 0.62869, 1, 0.56926, 1, 0.32887, 0.88007, 0.04472, 0.7649, 0, 0.61844, 0.14237, 0.48206, 0.16865, 0.34839, 0.03769, 0.00116, 0.67304, 0.01853 ], + "triangles": [ 11, 2, 10, 2, 9, 10, 3, 9, 2, 5, 6, 4, 3, 8, 9, 4, 8, 3, 6, 7, 8, 8, 4, 6, 2, 11, 1, 11, 12, 1, 12, 0, 1, 12, 13, 14, 12, 14, 0 ], + "vertices": [ 2, 20, -118.94, -74.62, 0.3588, 26, 247.8, 124.13, 0.6412, 3, 20, -239.77, -98.52, 0.2672, 26, 368.62, 148.04, 0.3511, 27, -100.02, 148.04, 0.3817, 3, 20, -328.96, -104.03, 0.19285, 26, 457.82, 153.54, 0.32625, 27, -10.83, 153.54, 0.4809, 3, 20, -405.92, -108.78, 0.12293, 26, 534.78, 158.3, 0.37135, 27, 66.13, 158.3, 0.50573, 3, 20, -492.62, -89.32, 0.05925, 26, 621.47, 138.84, 0.1867, 27, 152.83, 138.84, 0.75405, 2, 26, 702.38, 140.18, 0, 27, 233.73, 140.18, 1, 3, 20, -573.52, -27.46, 0.0224, 26, 702.38, 76.98, 0.06577, 27, 233.73, 76.98, 0.91183, 3, 20, -573.52, -14.45, 0.05056, 26, 702.38, 63.96, 0.14653, 27, 233.73, 63.96, 0.80292, 3, 20, -494.85, 38.2, 0.08885, 26, 623.7, 11.32, 0.25335, 27, 155.06, 11.32, 0.65779, 3, 20, -419.29, 100.43, 0.19057, 26, 548.15, -50.91, 0.36714, 27, 79.5, -50.91, 0.44229, 3, 20, -323.21, 110.22, 0.2672, 26, 452.07, -60.7, 0.2519, 27, -16.58, -60.7, 0.4809, 3, 20, -233.75, 79.04, 0.2672, 26, 362.61, -29.52, 0.3511, 27, -106.04, -29.52, 0.3817, 2, 20, -146.06, 73.29, 0.3588, 26, 274.92, -23.77, 0.6412, 1, 20, 81.72, 101.97, 1, 2, 20, 70.32, -37.17, 0.99873, 26, 58.53, 86.69, 0.00127 ], + "hull": 15, + "edges": [ 12, 14, 20, 22, 22, 24, 24, 26, 26, 28, 2, 4, 4, 6, 2, 0, 0, 28, 18, 20, 14, 16, 16, 18, 8, 10, 6, 8, 10, 12 ], + "width": 219, + "height": 656 + } + }, + "hair-back/hair-back-5": { + "hair-back-5": { + "type": "mesh", + "uvs": [ 0.52681, 0.0022, 0.53701, 0.13188, 0.57788, 0.19975, 0.74688, 0.40516, 0.89266, 0.58235, 1, 0.80234, 0.94757, 0.86532, 0.87274, 0.99806, 0.65652, 1, 0.49768, 0.91169, 0.26202, 0.78067, 0.35593, 0.58238, 0.25008, 0.42396, 0, 0.16031, 0, 0.12266, 0.22195, 0.00216 ], + "triangles": [ 8, 9, 7, 7, 9, 6, 6, 9, 5, 5, 9, 4, 9, 10, 4, 11, 4, 10, 11, 3, 4, 11, 12, 3, 12, 13, 2, 12, 2, 3, 15, 1, 14, 1, 15, 0, 2, 13, 1, 1, 13, 14 ], + "vertices": [ 1, 20, 168.95, -85.68, 1, 2, 20, 78.56, -87.92, 0.84015, 26, 50.29, 137.44, 0.15985, 2, 20, 31.25, -96.91, 0.67545, 26, 97.6, 146.43, 0.32455, 2, 20, -111.92, -134.09, 0.50775, 26, 240.77, 183.61, 0.49225, 2, 20, -235.42, -166.16, 0.34305, 26, 364.28, 215.68, 0.65695, 3, 20, -387.13, -190.07, 0.10437, 26, 515.98, 239.59, 0.36512, 27, 47.26, 237.59, 0.53051, 3, 20, -432.65, -178.24, 0.03859, 26, 561.5, 227.76, 0.18918, 27, 92.85, 227.76, 0.77223, 2, 26, 654.02, 211.3, 0.2137, 27, 185.38, 211.3, 0.7863, 2, 26, 655.38, 163.73, 0.2137, 27, 186.73, 163.73, 0.7863, 3, 20, -464.97, -79.27, 0.09122, 26, 593.83, 128.79, 0.40749, 27, 125.18, 128.79, 0.50129, 2, 20, -373.65, -27.42, 0.1832, 26, 502.5, 76.94, 0.8168, 2, 20, -235.44, -48.08, 0.38703, 26, 364.29, 97.6, 0.61297, 2, 20, -125.02, -24.8, 0.59141, 26, 253.87, 74.32, 0.40859, 1, 20, 58.74, 30.22, 1, 1, 20, 84.98, 30.22, 1, 1, 20, 168.97, -18.61, 1 ], + "hull": 16, + "edges": [ 0, 30, 0, 2, 2, 4, 14, 16, 20, 22, 26, 28, 28, 30, 10, 12, 12, 14, 16, 18, 18, 20, 4, 6, 6, 8, 24, 26, 22, 24, 18, 8, 8, 10 ], + "width": 220, + "height": 697 + } + }, + "hair-back/hair-back-6": { + "hair-back-6": { + "type": "mesh", + "uvs": [ 0, 0.00316, 0.19789, 0.00238, 0.24097, 0.10462, 0.42784, 0.26537, 0.57522, 0.34678, 0.68888, 0.40956, 0.80549, 0.47398, 0.94785, 0.55261, 0.89923, 0.64182, 0.84246, 0.74598, 1, 0.78199, 1, 0.82207, 0.92109, 0.94159, 0.77855, 1, 0.5892, 1, 0.4989, 0.90847, 0.38858, 0.79465, 0.39143, 0.71034, 0.43093, 0.64588, 0.41659, 0.56993, 0.34767, 0.47025, 0.25898, 0.39956, 0.12664, 0.29408, 0.0176, 0.20717, 0, 0.0579, 0.6061, 0.79944 ], + "triangles": [ 12, 13, 15, 13, 14, 15, 12, 15, 11, 11, 15, 9, 15, 16, 25, 15, 25, 9, 9, 10, 11, 25, 8, 9, 25, 16, 17, 8, 25, 17, 18, 8, 17, 18, 19, 8, 8, 19, 7, 19, 6, 7, 19, 20, 6, 20, 5, 6, 5, 21, 4, 5, 20, 21, 21, 3, 4, 21, 22, 3, 22, 23, 3, 23, 2, 3, 23, 24, 2, 24, 1, 2, 24, 0, 1 ], + "vertices": [ 1, 20, 167.22, -45.78, 1, 1, 20, 167.78, -89.31, 1, 3, 20, 94.68, -98.79, 0.86501, 26, 34.18, 148.31, 0.12237, 27, -434.47, 148.31, 0.01262, 3, 20, -20.26, -139.9, 0.73484, 26, 149.11, 189.42, 0.23236, 27, -319.53, 189.42, 0.03279, 3, 20, -78.47, -172.33, 0.6136, 26, 207.32, 221.85, 0.31854, 27, -261.32, 221.85, 0.06786, 3, 20, -123.36, -197.33, 0.50408, 26, 252.21, 246.85, 0.37201, 27, -216.43, 246.85, 0.12392, 3, 20, -169.41, -222.99, 0.40753, 26, 298.27, 272.51, 0.38856, 27, -170.38, 272.51, 0.20391, 3, 20, -225.64, -254.3, 0.32386, 26, 354.49, 303.82, 0.37034, 27, -114.15, 303.82, 0.3058, 3, 20, -289.42, -243.61, 0.25215, 26, 418.27, 293.13, 0.32576, 27, -50.37, 293.13, 0.42209, 3, 20, -363.9, -231.12, 0.20172, 26, 492.75, 280.64, 0.2532, 27, 24.1, 280.64, 0.54508, 3, 20, -389.64, -265.78, 0.16128, 26, 518.5, 315.3, 0.17872, 27, 49.85, 315.3, 0.65999, 3, 20, -418.3, -265.78, 0.10469, 26, 547.16, 315.3, 0.2824, 27, 78.51, 315.3, 0.61291, 3, 20, -503.76, -248.42, 0.07948, 26, 632.61, 297.94, 0.2824, 27, 163.97, 297.94, 0.63812, 3, 20, -545.52, -217.06, 0.06028, 26, 674.38, 266.58, 0.2824, 27, 205.73, 266.58, 0.65732, 3, 20, -545.52, -175.4, 0.06028, 26, 674.38, 224.92, 0.2824, 27, 205.73, 224.92, 0.65732, 3, 20, -480.08, -155.54, 0.15387, 26, 608.93, 205.05, 0.2824, 27, 140.29, 205.05, 0.56373, 3, 20, -398.7, -131.27, 0.25129, 26, 527.55, 180.79, 0.44103, 27, 58.91, 180.79, 0.30769, 3, 20, -338.41, -131.89, 0.2923, 26, 467.27, 181.41, 0.5779, 27, -1.38, 181.41, 0.1298, 3, 20, -292.32, -140.58, 0.37144, 26, 421.18, 190.1, 0.53386, 27, -47.47, 190.1, 0.0947, 3, 20, -238.02, -137.43, 0.45068, 26, 366.88, 186.95, 0.48817, 27, -101.77, 186.95, 0.06116, 3, 20, -166.75, -122.27, 0.53005, 26, 295.6, 171.78, 0.44014, 27, -173.04, 171.78, 0.0298, 2, 20, -116.21, -102.75, 0.60953, 26, 245.06, 152.27, 0.39047, 2, 20, -40.79, -73.64, 0.72471, 26, 169.64, 123.16, 0.27529, 2, 20, 21.35, -49.65, 0.8574, 26, 107.5, 99.17, 0.1426, 1, 20, 128.08, -45.78, 1, 3, 20, -402.12, -179.12, 0.19676, 26, 530.97, 228.64, 0.26884, 27, 62.33, 228.64, 0.5344 ], + "hull": 25, + "edges": [ 0, 48, 0, 2, 2, 4, 4, 6, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 38, 40, 46, 48, 12, 14, 10, 12, 44, 46, 40, 42, 42, 44, 6, 8, 8, 10, 36, 38, 14, 16, 16, 18, 32, 34, 34, 36, 28, 30, 30, 32, 50, 16, 18, 30 ], + "width": 220, + "height": 715 + } + }, + "hat/feathers-back": { + "feathers-back": { + "type": "mesh", + "uvs": [ 0.99999, 0, 1, 0.33648, 0.94897, 0.50948, 0.82521, 0.929, 0.47931, 1, 0.33408, 0.78083, 0.14308, 0.49259, 0, 0.27667, 0, 0.08318, 0.4705, 0.03304, 0.78052, 0, 0.66524, 0.5216, 0.59356, 0.18309, 0.6294, 0.3623 ], + "triangles": [ 1, 10, 0, 12, 10, 1, 6, 9, 12, 6, 7, 9, 6, 12, 13, 1, 13, 12, 3, 11, 2, 5, 6, 11, 3, 4, 11, 4, 5, 11, 6, 13, 11, 11, 13, 2, 2, 13, 1, 7, 8, 9, 12, 9, 10 ], + "vertices": [ 2, 24, 96.3, -42.01, 0.6031, 23, 91.5, -153.41, 0.3969, 2, 24, 57.96, -40.97, 0.2748, 23, 56.76, -137.15, 0.7252, 2, 24, 38.4, -34.62, 0.2748, 23, 41.37, -123.52, 0.7252, 1, 23, 4.03, -90.47, 1, 1, 23, 13.42, -51.32, 1, 1, 23, 43.07, -46.92, 1, 2, 24, 42.82, 57.17, 0.2748, 23, 82.06, -41.13, 0.7252, 2, 24, 67.87, 72.8, 0.6031, 23, 111.27, -36.79, 0.3969, 2, 24, 89.92, 72.2, 0.6031, 23, 131.24, -46.15, 0.3969, 2, 24, 94.18, 18.43, 0.6031, 23, 113.68, -97.15, 0.3969, 2, 24, 96.98, -17, 0.6031, 23, 102.11, -130.75, 0.3969, 2, 24, 37.9, -2.25, 0.2748, 23, 53.83, -93.64, 0.7252, 2, 24, 76.7, 4.87, 0.6031, 23, 92.24, -102.6, 0.3969, 2, 24, 56.16, 1.34, 0.2748, 23, 72.01, -97.64, 0.7252 ], + "hull": 11, + "edges": [ 0, 2, 14, 16, 8, 10, 10, 12, 12, 14, 16, 18, 18, 20, 20, 0, 2, 4, 4, 6, 24, 26, 24, 18, 26, 22, 6, 8 ], + "width": 114, + "height": 114 + } + }, + "hat/feathers-front": { + "feathers-front": { + "type": "mesh", + "uvs": [ 0.3388, 0, 0.54158, 0.14344, 0.74297, 0.2859, 0.85306, 0.36378, 1, 0.46773, 1, 0.60515, 0.95944, 0.81123, 0.66438, 1, 0.58726, 1, 0.56097, 0.78724, 0.54426, 0.65203, 0.40317, 0.57511, 0.19125, 0.45957, 0, 0.3553, 0, 1.0E-5, 0.75902, 0.42138, 0.75203, 0.58249, 0.74507, 0.72959, 0.79778, 0.42193, 0.78067, 0.58361 ], + "triangles": [ 19, 4, 5, 5, 17, 19, 7, 8, 9, 7, 17, 6, 17, 7, 9, 6, 17, 5, 0, 13, 14, 12, 0, 1, 12, 13, 0, 11, 12, 1, 11, 1, 2, 17, 10, 16, 17, 16, 19, 19, 18, 4, 15, 2, 3, 11, 2, 15, 15, 10, 11, 19, 15, 18, 16, 15, 19, 16, 10, 15, 9, 10, 17, 18, 15, 3, 18, 3, 4 ], + "vertices": [ 1, 25, 92.8, -22.38, 1, 2, 24, 174.08, 16.41, 0.21011, 25, 45.04, -23.75, 0.78989, 2, 24, 142.48, -18.99, 0.41348, 25, -2.4, -25.11, 0.58652, 2, 24, 125.2, -38.35, 0.5954, 23, 119.46, -161.59, 0.4046, 2, 24, 102.14, -64.18, 0.5954, 23, 88.01, -176.07, 0.4046, 2, 24, 72.6, -63.38, 0.3969, 23, 61.25, -163.54, 0.6031, 2, 24, 28.51, -54.87, 0.1298, 23, 24.22, -138.15, 0.8702, 1, 23, 9.97, -72.84, 1, 1, 23, 15.86, -60.27, 1, 2, 24, 35.62, 16.68, 0.458, 23, 59.29, -75.37, 0.542, 3, 24, 64.76, 18.9, 0.51591, 25, -28.26, 57.4, 0.2824, 23, 86.9, -84.97, 0.20169, 2, 24, 81.98, 43.84, 0.5618, 25, 1.7, 62.01, 0.4382, 2, 24, 107.85, 81.29, 0.37966, 25, 46.68, 68.95, 0.62034, 2, 24, 131.2, 115.1, 0.19036, 25, 87.29, 75.21, 0.80964, 1, 25, 138.24, 18.29, 1, 2, 24, 113.28, -21.09, 0.76701, 25, -23.98, -5.33, 0.23299, 3, 24, 78.69, -18.89, 0.55872, 25, -46.15, 21.31, 0.2824, 23, 84.58, -125.18, 0.15888, 3, 24, 47.11, -16.78, 0.28286, 25, -66.31, 45.71, 0.3824, 23, 56.47, -110.64, 0.33474, 2, 24, 112.97, -28.06, 0.5954, 23, 112.36, -147.28, 0.4046, 2, 24, 78.31, -24.04, 0.3969, 23, 82.18, -129.75, 0.6031 ], + "hull": 15, + "edges": [ 8, 10, 10, 12, 12, 14, 14, 16, 28, 0, 26, 28, 24, 26, 0, 2, 2, 4, 20, 22, 22, 24, 16, 18, 18, 20, 4, 6, 6, 8 ], + "width": 180, + "height": 215 + } + }, + "hat/hat-back": { + "hat-back": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 3, 0, 1, 2, 3 ], + "vertices": [ 1, 23, -51.19, -50.19, 1, 2, 22, 56.23, -21.15, 0.2791, 23, 16.22, 93.82, 0.7209, 2, 22, 168.23, -21.15, 0.2791, 23, 117.65, 46.34, 0.7209, 1, 23, 50.25, -97.67, 1 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 159, + "height": 112 + } + }, + "hat/hat-front": { + "hat-front": { + "type": "mesh", + "uvs": [ 1, 1, 0, 1, 0, 0, 1, 0 ], + "triangles": [ 1, 2, 3, 1, 3, 0 ], + "vertices": [ 2, 28, 83.32, -0.11, 0.1628, 23, -118.89, -79.23, 0.8372, 2, 22, 7.23, 5.85, 0.2636, 23, -16.72, 139.05, 0.7364, 2, 22, 147.23, 5.85, 0.2636, 23, 110.08, 79.69, 0.7364, 2, 28, 223.32, -0.11, 0.1628, 23, 7.91, -138.58, 0.8372 ], + "hull": 4, + "edges": [ 0, 2, 2, 4, 4, 6, 0, 6 ], + "width": 241, + "height": 140 + } + }, + "stars/star1": { + "star-big": { "width": 44, "height": 60 }, + "star-medium": { "width": 14, "height": 20 }, + "star-small": { "width": 8, "height": 11 } + }, + "stars/star2": { + "star-big": { "width": 44, "height": 60 }, + "star-medium": { "width": 14, "height": 20 }, + "star-small": { "width": 8, "height": 11 } + }, + "stars/star3": { + "star-big": { "width": 44, "height": 60 }, + "star-medium": { "width": 14, "height": 20 }, + "star-small": { "width": 8, "height": 11 } + }, + "stars/star4": { + "star-big": { "width": 44, "height": 60 }, + "star-medium": { "width": 14, "height": 20 }, + "star-small": { "width": 8, "height": 11 } + }, + "stars/star5": { + "star-big": { "width": 44, "height": 60 }, + "star-medium": { "width": 14, "height": 20 }, + "star-small": { "width": 8, "height": 11 } + }, + "stars/star6": { + "star-big": { "width": 44, "height": 60 }, + "star-medium": { "width": 14, "height": 20 }, + "star-small": { "width": 8, "height": 11 } + } + } + } +], +"animations": { + "eyeblink": { + "bones": { + "eyelashes-top-front": { + "translate": [ + { + "curve": [ 0.061, 0, 0.071, -26.84, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -26.84, + "curve": [ 0.282, -26.84, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-top-back": { + "translate": [ + { + "curve": [ 0.061, 0, 0.071, -22.55, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -22.55, + "curve": [ 0.282, -22.55, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-down-front": { + "translate": [ + { + "curve": [ 0.061, 0, 0.071, 12.12, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": 12.12, + "curve": [ 0.282, 12.12, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-down-back": { + "translate": [ + { + "curve": [ 0.061, 0, 0.071, 10.12, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": 10.12, + "curve": [ 0.282, 10.12, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ] + }, + "pupil-front": { + "translate": [ + { + "curve": [ 0.061, 0, 0.071, -6.11, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -6.11, + "curve": [ 0.282, -6.11, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ], + "scale": [ + { + "curve": [ 0.061, 1, 0.071, 0.152, 0.029, 1, 0.071, 1 ] + }, + { + "time": 0.1, + "x": 0.152, + "curve": [ 0.282, 0.152, 0.244, 1, 0.183, 1, 0.25, 1 ] + }, + { "time": 0.3333 } + ] + }, + "pupil-back": { + "translate": [ + { + "curve": [ 0.061, 0, 0.071, -6.11, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -6.11, + "curve": [ 0.282, -6.11, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ], + "scale": [ + { + "curve": [ 0.061, 1, 0.071, 0.152, 0.029, 1, 0.071, 1 ] + }, + { + "time": 0.1, + "x": 0.152, + "curve": [ 0.282, 0.152, 0.244, 1, 0.183, 1, 0.25, 1 ] + }, + { "time": 0.3333 } + ] + } + } + }, + "eyeblink-long": { + "bones": { + "eyelashes-top-front": { + "translate": [ + { + "curve": [ 0.06, 0, 0.071, -26.84, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -26.84, + "curve": [ 0.278, -26.84, 0.246, 0, 0.182, 0, 0.252, 0 ] + }, + { "time": 0.3333, "curve": "stepped" }, + { "time": 4.7 } + ] + }, + "eyelashes-top-back": { + "translate": [ + { + "curve": [ 0.06, 0, 0.071, -22.55, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -22.55, + "curve": [ 0.278, -22.55, 0.246, 0, 0.182, 0, 0.252, 0 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-down-front": { + "translate": [ + { + "curve": [ 0.06, 0, 0.071, 12.12, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": 12.12, + "curve": [ 0.278, 12.12, 0.246, 0, 0.182, 0, 0.252, 0 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-down-back": { + "translate": [ + { + "curve": [ 0.06, 0, 0.071, 10.12, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": 10.12, + "curve": [ 0.278, 10.12, 0.246, 0, 0.182, 0, 0.252, 0 ] + }, + { "time": 0.3333 } + ] + }, + "pupil-front": { + "translate": [ + { + "curve": [ 0.06, 0, 0.071, -6.11, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -6.11, + "curve": [ 0.278, -6.11, 0.246, 0, 0.182, 0, 0.252, 0 ] + }, + { "time": 0.3333 } + ], + "scale": [ + { + "curve": [ 0.06, 1, 0.071, 0.152, 0.029, 1, 0.071, 1 ] + }, + { + "time": 0.1, + "x": 0.152, + "curve": [ 0.278, 0.152, 0.246, 1, 0.182, 1, 0.252, 1 ] + }, + { "time": 0.3333 } + ] + }, + "pupil-back": { + "translate": [ + { + "curve": [ 0.06, 0, 0.071, -6.11, 0.029, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": -6.11, + "curve": [ 0.278, -6.11, 0.246, 0, 0.182, 0, 0.252, 0 ] + }, + { "time": 0.3333 } + ], + "scale": [ + { + "curve": [ 0.06, 1, 0.071, 0.152, 0.029, 1, 0.071, 1 ] + }, + { + "time": 0.1, + "x": 0.152, + "curve": [ 0.278, 0.152, 0.246, 1, 0.182, 1, 0.252, 1 ] + }, + { "time": 0.3333 } + ] + } + } + }, + "stars": { + "slots": { + "stars/star1": { + "attachment": [ + { "time": 0.0667, "name": "star-small" }, + { "time": 0.1333, "name": "star-medium" }, + { "time": 0.2, "name": "star-big" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4 } + ] + }, + "stars/star2": { + "attachment": [ + { "time": 0.0667, "name": "star-small" }, + { "time": 0.1333, "name": "star-medium" }, + { "time": 0.2, "name": "star-big" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4 } + ] + }, + "stars/star3": { + "attachment": [ + { "time": 0.0667, "name": "star-small" }, + { "time": 0.1333, "name": "star-medium" }, + { "time": 0.2, "name": "star-big" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4 } + ] + }, + "stars/star4": { + "attachment": [ + { "time": 0.4, "name": "star-small" }, + { "time": 0.4667, "name": "star-medium" }, + { "time": 0.5333, "name": "star-big" }, + { "time": 0.6, "name": "star-medium" }, + { "time": 0.6667, "name": "star-small" }, + { "time": 0.7333 } + ] + }, + "stars/star5": { + "attachment": [ + { "time": 0.1667, "name": "star-small" }, + { "time": 0.2333, "name": "star-medium" }, + { "time": 0.3, "name": "star-big" }, + { "time": 0.3667, "name": "star-medium" }, + { "time": 0.4333, "name": "star-small" }, + { "time": 0.5 } + ] + }, + "stars/star6": { + "attachment": [ + { "time": 0.4, "name": "star-small" }, + { "time": 0.4667, "name": "star-medium" }, + { "time": 0.5333, "name": "star-big" }, + { "time": 0.6, "name": "star-medium" }, + { "time": 0.6667, "name": "star-small" }, + { "time": 0.7333 } + ] + } + } + }, + "swing": { + "slots": { + "stars/star1": { + "attachment": [ + { "time": 0.0667, "name": "star-small" }, + { "time": 0.1333, "name": "star-medium" }, + { "time": 0.2, "name": "star-big" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4 }, + { "time": 0.8, "name": "star-small" }, + { "time": 0.8667, "name": "star-medium" }, + { "time": 0.9333, "name": "star-big" }, + { "time": 1, "name": "star-medium" }, + { "time": 1.0667, "name": "star-small" }, + { "time": 1.1333 }, + { "time": 1.5333, "name": "star-small" }, + { "time": 1.6, "name": "star-medium" }, + { "time": 1.6667, "name": "star-big" }, + { "time": 1.7333, "name": "star-medium" }, + { "time": 1.8, "name": "star-small" }, + { "time": 1.8667 } + ] + }, + "stars/star2": { + "attachment": [ + { "time": 0.0667, "name": "star-small" }, + { "time": 0.1333, "name": "star-medium" }, + { "time": 0.2, "name": "star-big" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4 }, + { "time": 0.8, "name": "star-small" }, + { "time": 0.8667, "name": "star-medium" }, + { "time": 0.9333, "name": "star-big" }, + { "time": 1, "name": "star-medium" }, + { "time": 1.0667, "name": "star-small" }, + { "time": 1.1333 }, + { "time": 1.5333, "name": "star-small" }, + { "time": 1.6, "name": "star-medium" }, + { "time": 1.6667, "name": "star-big" }, + { "time": 1.7333, "name": "star-medium" }, + { "time": 1.8, "name": "star-small" }, + { "time": 1.8667 } + ] + }, + "stars/star3": { + "attachment": [ + { "time": 0.0667, "name": "star-small" }, + { "time": 0.1333, "name": "star-medium" }, + { "time": 0.2, "name": "star-big" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4 }, + { "time": 0.8, "name": "star-small" }, + { "time": 0.8667, "name": "star-medium" }, + { "time": 0.9333, "name": "star-big" }, + { "time": 1, "name": "star-medium" }, + { "time": 1.0667, "name": "star-small" }, + { "time": 1.1333 }, + { "time": 1.5333, "name": "star-small" }, + { "time": 1.6, "name": "star-medium" }, + { "time": 1.6667, "name": "star-big" }, + { "time": 1.7333, "name": "star-medium" }, + { "time": 1.8, "name": "star-small" }, + { "time": 1.8667 } + ] + }, + "stars/star4": { + "attachment": [ + { "time": 0.4, "name": "star-small" }, + { "time": 0.4667, "name": "star-medium" }, + { "time": 0.5333, "name": "star-big" }, + { "time": 0.6, "name": "star-medium" }, + { "time": 0.6667, "name": "star-small" }, + { "time": 0.7333 }, + { "time": 1.1333, "name": "star-small" }, + { "time": 1.2, "name": "star-medium" }, + { "time": 1.2667, "name": "star-big" }, + { "time": 1.3333, "name": "star-medium" }, + { "time": 1.4, "name": "star-small" }, + { "time": 1.4667 }, + { "time": 1.8667, "name": "star-small" }, + { "time": 1.9333, "name": "star-medium" }, + { "time": 2, "name": "star-big" }, + { "time": 2.0667, "name": "star-medium" }, + { "time": 2.1333, "name": "star-small" }, + { "time": 2.2 } + ] + }, + "stars/star5": { + "attachment": [ + { "time": 0.1667, "name": "star-small" }, + { "time": 0.2333, "name": "star-medium" }, + { "time": 0.3, "name": "star-big" }, + { "time": 0.3667, "name": "star-medium" }, + { "time": 0.4333, "name": "star-small" }, + { "time": 0.5 }, + { "time": 0.9, "name": "star-small" }, + { "time": 0.9667, "name": "star-medium" }, + { "time": 1.0333, "name": "star-big" }, + { "time": 1.1, "name": "star-medium" }, + { "time": 1.1667, "name": "star-small" }, + { "time": 1.2333 }, + { "time": 1.6333, "name": "star-small" }, + { "time": 1.7, "name": "star-medium" }, + { "time": 1.7667, "name": "star-big" }, + { "time": 1.8333, "name": "star-medium" }, + { "time": 1.9, "name": "star-small" }, + { "time": 1.9667 } + ] + }, + "stars/star6": { + "attachment": [ + { "time": 0.4, "name": "star-small" }, + { "time": 0.4667, "name": "star-medium" }, + { "time": 0.5333, "name": "star-big" }, + { "time": 0.6, "name": "star-medium" }, + { "time": 0.6667, "name": "star-small" }, + { "time": 0.7333 }, + { "time": 1.1333, "name": "star-small" }, + { "time": 1.2, "name": "star-medium" }, + { "time": 1.2667, "name": "star-big" }, + { "time": 1.3333, "name": "star-medium" }, + { "time": 1.4, "name": "star-small" }, + { "time": 1.4667 }, + { "time": 1.8667, "name": "star-small" }, + { "time": 1.9333, "name": "star-medium" }, + { "time": 2, "name": "star-big" }, + { "time": 2.0667, "name": "star-medium" }, + { "time": 2.1333, "name": "star-small" }, + { "time": 2.2 } + ] + } + }, + "bones": { + "swing-top": { + "rotate": [ + { + "value": -13.18, + "curve": [ 0.607, -13.18, 0.733, 15.86 ] + }, + { + "time": 1.1, + "value": 15.86, + "curve": [ 1.707, 15.86, 1.833, -13.18 ] + }, + { "time": 2.2, "value": -13.18 } + ] + }, + "swing-bottom": { + "rotate": [ + { + "value": 0.37, + "curve": [ 0.145, -6.53, 0.258, -13.18 ] + }, + { + "time": 0.4333, + "value": -13.18, + "curve": [ 1.04, -13.18, 1.166, 15.86 ] + }, + { + "time": 1.5333, + "value": 15.86, + "curve": [ 1.851, 15.86, 2.043, 7.96 ] + }, + { "time": 2.2, "value": 0.37 } + ] + }, + "body-up": { + "rotate": [ + { + "value": 11.88, + "curve": [ 0.368, 11.88, 0.732, -7.09 ] + }, + { + "time": 1.1, + "value": -7.09, + "curve": [ 1.468, -7.09, 1.832, 11.88 ] + }, + { "time": 2.2, "value": 11.88 } + ] + }, + "neck": { + "rotate": [ + { + "value": -14.54, + "curve": [ 0.357, -14.54, 0.709, 16.44 ] + }, + { + "time": 1.0667, + "value": 16.44, + "curve": [ 1.445, 16.44, 1.822, -14.54 ] + }, + { "time": 2.2, "value": -14.54 } + ] + }, + "face-control": { + "translate": [ + { "y": 14.53 }, + { "time": 1.0333, "x": -1.18, "y": -10.95 }, + { "time": 2.2, "y": 14.53 } + ] + }, + "pupil-front": { + "translate": [ + {}, + { "time": 1.1, "x": -7.23, "y": -2.49 }, + { "time": 2.2 } + ] + }, + "pupil-back": { + "translate": [ + {}, + { "time": 1.1, "x": -7.23, "y": -2.49 }, + { "time": 2.2 } + ] + }, + "eyelashes-top-front": { + "translate": [ + {}, + { "time": 1, "x": -7.38 }, + { "time": 2.2 } + ] + }, + "eyelashes-top-back": { + "translate": [ + {}, + { "time": 1, "x": -7.38 }, + { "time": 2.2 } + ] + }, + "mouth": { + "scale": [ + {}, + { "time": 0.9333, "x": 0.848, "y": 1.067 }, + { "time": 2.2 } + ] + }, + "face": { + "translate": [ + {}, + { "time": 0.6667, "x": -13.93, "y": -16.25 }, + { "time": 1.6, "x": 5.02, "y": -6.3 }, + { "time": 2.2 } + ] + }, + "wing-front-tip": { + "rotate": [ + { + "value": -5.65, + "curve": [ 0.148, -14.43, 0.293, -30.34 ] + }, + { + "time": 0.4667, + "value": -30.34, + "curve": [ 0.661, -30.34, 0.822, -11.79 ] + }, + { "time": 1 }, + { + "time": 1.5, + "value": 33.17, + "curve": [ 1.691, 33.17, 1.864, 0 ] + }, + { + "time": 2.0333, + "curve": [ 2.091, 0, 2.146, -2.29 ] + }, + { "time": 2.2, "value": -5.65 } + ] + }, + "wing-front": { + "rotate": [ + { "value": -28.71 }, + { "time": 1, "value": 12.5 }, + { "time": 2.2, "value": -28.71 } + ], + "scale": [ + { "y": 0.497 }, + { "time": 1 }, + { "time": 2.2, "y": 0.497 } + ] + }, + "wing-back": { + "rotate": [ + { + "value": 31.82, + "curve": [ 0.359, 31.82, 0.667, 15.27 ] + }, + { + "time": 1, + "value": 15.27, + "curve": [ 1.37, 15.27, 1.83, 31.82 ] + }, + { "time": 2.2, "value": 31.82 } + ], + "scale": [ + { + "x": 1.248, + "y": 0.376, + "curve": [ 0.359, 1.248, 0.667, 1, 0.359, 0.376, 0.667, 1 ] + }, + { + "time": 1, + "curve": [ 1.37, 1, 1.83, 1.248, 1.37, 1, 1.83, 0.376 ] + }, + { "time": 2.2, "x": 1.248, "y": 0.376 } + ] + }, + "wing-back-tip": { + "rotate": [ + { + "value": 3.37, + "curve": [ 0.148, 8.61, 0.293, 18.1 ] + }, + { + "time": 0.4667, + "value": 18.1, + "curve": [ 0.661, 18.1, 0.822, 10.98 ] + }, + { "time": 1 }, + { "time": 1.5667, "value": 11.59 }, + { "time": 2.2, "value": 3.37 } + ], + "scale": [ + { + "x": 1.122, + "curve": [ 0.157, 1.173, 0.295, 1.246, 0.157, 1, 0.295, 1 ] + }, + { + "time": 0.4667, + "x": 1.222, + "curve": [ 0.647, 1.198, 0.822, 0.499, 0.647, 1, 0.822, 1 ] + }, + { + "time": 1, + "x": 0.499, + "curve": [ 1.175, 0.499, 2.151, 1.105, 1.175, 1, 2.151, 1 ] + }, + { "time": 2.2, "x": 1.122 } + ] + }, + "cloud": { + "rotate": [ + { + "value": -0.49, + "curve": [ 0.135, -1.47, 0.268, -2.39 ] + }, + { + "time": 0.4, + "value": -2.78, + "curve": [ 0.445, -2.91, 0.489, -3 ] + }, + { + "time": 0.5333, + "value": -3, + "curve": [ 0.867, -3, 1.2, 3 ] + }, + { + "time": 1.5333, + "value": 3, + "curve": [ 1.756, 3, 1.98, 1.16 ] + }, + { "time": 2.2, "value": -0.49 } + ], + "translate": [ + { + "x": -150, + "curve": [ 0.557, -150, 0.55, 146.39, 0.333, 0, 0.667, 0 ] + }, + { + "time": 1, + "x": 150, + "curve": [ 1.668, 155.35, 1.8, -150, 1.4, 0, 1.8, 0 ] + }, + { "time": 2.2, "x": -150 } + ] + }, + "rope-back": { + "translate": [ + {}, + { "time": 1, "y": -1.11 }, + { "time": 2.2 } + ] + }, + "bench-front": { + "translate": [ + {}, + { "time": 1, "y": 120.63 }, + { "time": 2.2 } + ] + }, + "bench-back": { + "translate": [ + {}, + { "time": 1, "x": -11.37 }, + { "time": 2.2 } + ] + }, + "rope-front": { + "translate": [ + {}, + { "time": 1, "y": 91.13 }, + { "time": 2.2 } + ] + } + } + }, + "wind-idle": { + "slots": { + "stars/star1": { + "attachment": [ + { "time": 0.1333, "name": "star-small" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.4, "name": "star-big" }, + { "time": 0.5, "name": "star-medium" }, + { "time": 0.6333, "name": "star-small" }, + { "time": 0.7667 }, + { "time": 1.6667, "name": "star-small" }, + { "time": 1.7333, "name": "star-medium" }, + { "time": 1.8, "name": "star-big" }, + { "time": 1.8667, "name": "star-medium" }, + { "time": 1.9333, "name": "star-small" }, + { "time": 2 }, + { "time": 2.4667, "name": "star-small" }, + { "time": 2.5333, "name": "star-medium" }, + { "time": 2.5667, "name": "star-big" }, + { "time": 2.6333, "name": "star-medium" }, + { "time": 2.7, "name": "star-small" }, + { "time": 2.7667 }, + { "time": 3.4, "name": "star-small" }, + { "time": 3.5333, "name": "star-medium" }, + { "time": 3.6333, "name": "star-big" }, + { "time": 3.7667, "name": "star-medium" }, + { "time": 3.9, "name": "star-small" }, + { "time": 4.0333 }, + { "time": 4.9333, "name": "star-small" }, + { "time": 5, "name": "star-medium" }, + { "time": 5.0667, "name": "star-big" }, + { "time": 5.1333, "name": "star-medium" }, + { "time": 5.2, "name": "star-small" }, + { "time": 5.2667 }, + { "time": 5.7, "name": "star-small" }, + { "time": 5.7667, "name": "star-medium" }, + { "time": 5.8333, "name": "star-big" }, + { "time": 5.9, "name": "star-medium" }, + { "time": 5.9667, "name": "star-small" }, + { "time": 6.0333 }, + { "time": 6.6333, "name": "star-small" }, + { "time": 6.7333, "name": "star-medium" }, + { "time": 6.8667, "name": "star-big" }, + { "time": 7, "name": "star-medium" }, + { "time": 7.1333, "name": "star-small" }, + { "time": 7.2667 }, + { "time": 8.1667, "name": "star-small" }, + { "time": 8.2333, "name": "star-medium" }, + { "time": 8.3, "name": "star-big" }, + { "time": 8.3667, "name": "star-medium" }, + { "time": 8.4333, "name": "star-small" }, + { "time": 8.5 }, + { "time": 8.9333, "name": "star-small" }, + { "time": 9, "name": "star-medium" }, + { "time": 9.0667, "name": "star-big" }, + { "time": 9.1333, "name": "star-medium" }, + { "time": 9.2, "name": "star-small" }, + { "time": 9.2667 } + ] + }, + "stars/star2": { + "attachment": [ + { "time": 0.1333, "name": "star-small" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.4, "name": "star-big" }, + { "time": 0.5, "name": "star-medium" }, + { "time": 0.6333, "name": "star-small" }, + { "time": 0.7667 }, + { "time": 1.6667, "name": "star-small" }, + { "time": 1.7333, "name": "star-medium" }, + { "time": 1.8, "name": "star-big" }, + { "time": 1.8667, "name": "star-medium" }, + { "time": 1.9333, "name": "star-small" }, + { "time": 2 }, + { "time": 2.4667, "name": "star-small" }, + { "time": 2.5333, "name": "star-medium" }, + { "time": 2.5667, "name": "star-big" }, + { "time": 2.6333, "name": "star-medium" }, + { "time": 2.7, "name": "star-small" }, + { "time": 2.7667 }, + { "time": 3.4, "name": "star-small" }, + { "time": 3.5333, "name": "star-medium" }, + { "time": 3.6333, "name": "star-big" }, + { "time": 3.7667, "name": "star-medium" }, + { "time": 3.9, "name": "star-small" }, + { "time": 4.0333 }, + { "time": 4.9333, "name": "star-small" }, + { "time": 5, "name": "star-medium" }, + { "time": 5.0667, "name": "star-big" }, + { "time": 5.1333, "name": "star-medium" }, + { "time": 5.2, "name": "star-small" }, + { "time": 5.2667 }, + { "time": 5.7, "name": "star-small" }, + { "time": 5.7667, "name": "star-medium" }, + { "time": 5.8333, "name": "star-big" }, + { "time": 5.9, "name": "star-medium" }, + { "time": 5.9667, "name": "star-small" }, + { "time": 6.0333 }, + { "time": 6.6333, "name": "star-small" }, + { "time": 6.7333, "name": "star-medium" }, + { "time": 6.8667, "name": "star-big" }, + { "time": 7, "name": "star-medium" }, + { "time": 7.1333, "name": "star-small" }, + { "time": 7.2667 }, + { "time": 8.1667, "name": "star-small" }, + { "time": 8.2333, "name": "star-medium" }, + { "time": 8.3, "name": "star-big" }, + { "time": 8.3667, "name": "star-medium" }, + { "time": 8.4333, "name": "star-small" }, + { "time": 8.5 }, + { "time": 8.9333, "name": "star-small" }, + { "time": 9, "name": "star-medium" }, + { "time": 9.0667, "name": "star-big" }, + { "time": 9.1333, "name": "star-medium" }, + { "time": 9.2, "name": "star-small" }, + { "time": 9.2667 } + ] + }, + "stars/star3": { + "attachment": [ + { "time": 0.1333, "name": "star-small" }, + { "time": 0.2667, "name": "star-medium" }, + { "time": 0.4, "name": "star-big" }, + { "time": 0.5, "name": "star-medium" }, + { "time": 0.6333, "name": "star-small" }, + { "time": 0.7667 }, + { "time": 1.6667, "name": "star-small" }, + { "time": 1.7333, "name": "star-medium" }, + { "time": 1.8, "name": "star-big" }, + { "time": 1.8667, "name": "star-medium" }, + { "time": 1.9333, "name": "star-small" }, + { "time": 2 }, + { "time": 2.4667, "name": "star-small" }, + { "time": 2.5333, "name": "star-medium" }, + { "time": 2.5667, "name": "star-big" }, + { "time": 2.6333, "name": "star-medium" }, + { "time": 2.7, "name": "star-small" }, + { "time": 2.7667 }, + { "time": 3.4, "name": "star-small" }, + { "time": 3.5333, "name": "star-medium" }, + { "time": 3.6333, "name": "star-big" }, + { "time": 3.7667, "name": "star-medium" }, + { "time": 3.9, "name": "star-small" }, + { "time": 4.0333 }, + { "time": 4.9333, "name": "star-small" }, + { "time": 5, "name": "star-medium" }, + { "time": 5.0667, "name": "star-big" }, + { "time": 5.1333, "name": "star-medium" }, + { "time": 5.2, "name": "star-small" }, + { "time": 5.2667 }, + { "time": 5.7, "name": "star-small" }, + { "time": 5.7667, "name": "star-medium" }, + { "time": 5.8333, "name": "star-big" }, + { "time": 5.9, "name": "star-medium" }, + { "time": 5.9667, "name": "star-small" }, + { "time": 6.0333 }, + { "time": 6.6333, "name": "star-small" }, + { "time": 6.7333, "name": "star-medium" }, + { "time": 6.8667, "name": "star-big" }, + { "time": 7, "name": "star-medium" }, + { "time": 7.1333, "name": "star-small" }, + { "time": 7.2667 }, + { "time": 8.1667, "name": "star-small" }, + { "time": 8.2333, "name": "star-medium" }, + { "time": 8.3, "name": "star-big" }, + { "time": 8.3667, "name": "star-medium" }, + { "time": 8.4333, "name": "star-small" }, + { "time": 8.5 }, + { "time": 8.9333, "name": "star-small" }, + { "time": 9, "name": "star-medium" }, + { "time": 9.0667, "name": "star-big" }, + { "time": 9.1333, "name": "star-medium" }, + { "time": 9.2, "name": "star-small" }, + { "time": 9.2667 } + ] + }, + "stars/star4": { + "attachment": [ + { "time": 0.7667, "name": "star-small" }, + { "time": 0.9, "name": "star-medium" }, + { "time": 1.0333, "name": "star-big" }, + { "time": 1.1667, "name": "star-medium" }, + { "time": 1.2667, "name": "star-small" }, + { "time": 1.4 }, + { "time": 2, "name": "star-small" }, + { "time": 2.0667, "name": "star-medium" }, + { "time": 2.1333, "name": "star-big" }, + { "time": 2.2, "name": "star-medium" }, + { "time": 2.2667, "name": "star-small" }, + { "time": 2.3333 }, + { "time": 2.7667, "name": "star-small" }, + { "time": 2.8333, "name": "star-medium" }, + { "time": 2.9, "name": "star-big" }, + { "time": 2.9667, "name": "star-medium" }, + { "time": 3.0333, "name": "star-small" }, + { "time": 3.1 }, + { "time": 4.0333, "name": "star-small" }, + { "time": 4.1667, "name": "star-medium" }, + { "time": 4.3, "name": "star-big" }, + { "time": 4.4333, "name": "star-medium" }, + { "time": 4.5333, "name": "star-small" }, + { "time": 4.6333 }, + { "time": 5.2667, "name": "star-small" }, + { "time": 5.3333, "name": "star-medium" }, + { "time": 5.4, "name": "star-big" }, + { "time": 5.4667, "name": "star-medium" }, + { "time": 5.5333, "name": "star-small" }, + { "time": 5.6 }, + { "time": 6.0333, "name": "star-small" }, + { "time": 6.1, "name": "star-medium" }, + { "time": 6.1667, "name": "star-big" }, + { "time": 6.2333, "name": "star-medium" }, + { "time": 6.3, "name": "star-small" }, + { "time": 6.3667 }, + { "time": 7.2667, "name": "star-small" }, + { "time": 7.4, "name": "star-medium" }, + { "time": 7.5333, "name": "star-big" }, + { "time": 7.6667, "name": "star-medium" }, + { "time": 7.7333, "name": "star-small" }, + { "time": 7.8667 }, + { "time": 8.5, "name": "star-small" }, + { "time": 8.5667, "name": "star-medium" }, + { "time": 8.6333, "name": "star-big" }, + { "time": 8.7, "name": "star-medium" }, + { "time": 8.7333, "name": "star-small" }, + { "time": 8.8 }, + { "time": 9.2667, "name": "star-small" }, + { "time": 9.3333, "name": "star-medium" }, + { "time": 9.4, "name": "star-big" }, + { "time": 9.4667, "name": "star-medium" }, + { "time": 9.5333, "name": "star-small" }, + { "time": 9.6 } + ] + }, + "stars/star5": { + "attachment": [ + { "time": 0.3333, "name": "star-small" }, + { "time": 0.4667, "name": "star-medium" }, + { "time": 0.5667, "name": "star-big" }, + { "time": 0.7, "name": "star-medium" }, + { "time": 0.8333, "name": "star-small" }, + { "time": 0.9667 }, + { "time": 1.7667, "name": "star-small" }, + { "time": 1.8333, "name": "star-medium" }, + { "time": 1.9, "name": "star-big" }, + { "time": 1.9667, "name": "star-medium" }, + { "time": 2.0333, "name": "star-small" }, + { "time": 2.1 }, + { "time": 2.5667, "name": "star-small" }, + { "time": 2.6, "name": "star-medium" }, + { "time": 2.6667, "name": "star-big" }, + { "time": 2.7333, "name": "star-medium" }, + { "time": 2.8, "name": "star-small" }, + { "time": 2.8667 }, + { "time": 3.6, "name": "star-small" }, + { "time": 3.7, "name": "star-medium" }, + { "time": 3.8333, "name": "star-big" }, + { "time": 3.9667, "name": "star-medium" }, + { "time": 4.1, "name": "star-small" }, + { "time": 4.2333 }, + { "time": 5.0333, "name": "star-small" }, + { "time": 5.1, "name": "star-medium" }, + { "time": 5.1667, "name": "star-big" }, + { "time": 5.2333, "name": "star-medium" }, + { "time": 5.3, "name": "star-small" }, + { "time": 5.3667 }, + { "time": 5.8, "name": "star-small" }, + { "time": 5.8667, "name": "star-medium" }, + { "time": 5.9333, "name": "star-big" }, + { "time": 6, "name": "star-medium" }, + { "time": 6.0667, "name": "star-small" }, + { "time": 6.1333 }, + { "time": 6.8, "name": "star-small" }, + { "time": 6.9333, "name": "star-medium" }, + { "time": 7.0667, "name": "star-big" }, + { "time": 7.2, "name": "star-medium" }, + { "time": 7.3333, "name": "star-small" }, + { "time": 7.4667 }, + { "time": 8.2667, "name": "star-small" }, + { "time": 8.3333, "name": "star-medium" }, + { "time": 8.4, "name": "star-big" }, + { "time": 8.4667, "name": "star-medium" }, + { "time": 8.5333, "name": "star-small" }, + { "time": 8.6 }, + { "time": 9.0333, "name": "star-small" }, + { "time": 9.1, "name": "star-medium" }, + { "time": 9.1667, "name": "star-big" }, + { "time": 9.2333, "name": "star-medium" }, + { "time": 9.3, "name": "star-small" }, + { "time": 9.3667 } + ] + }, + "stars/star6": { + "attachment": [ + { "time": 0.7667, "name": "star-small" }, + { "time": 0.9, "name": "star-medium" }, + { "time": 1.0333, "name": "star-big" }, + { "time": 1.1667, "name": "star-medium" }, + { "time": 1.2667, "name": "star-small" }, + { "time": 1.4 }, + { "time": 2, "name": "star-small" }, + { "time": 2.0667, "name": "star-medium" }, + { "time": 2.1333, "name": "star-big" }, + { "time": 2.2, "name": "star-medium" }, + { "time": 2.2667, "name": "star-small" }, + { "time": 2.3333 }, + { "time": 2.7667, "name": "star-small" }, + { "time": 2.8333, "name": "star-medium" }, + { "time": 2.9, "name": "star-big" }, + { "time": 2.9667, "name": "star-medium" }, + { "time": 3.0333, "name": "star-small" }, + { "time": 3.1 }, + { "time": 4.0333, "name": "star-small" }, + { "time": 4.1667, "name": "star-medium" }, + { "time": 4.3, "name": "star-big" }, + { "time": 4.4333, "name": "star-medium" }, + { "time": 4.5333, "name": "star-small" }, + { "time": 4.6333 }, + { "time": 5.2667, "name": "star-small" }, + { "time": 5.3333, "name": "star-medium" }, + { "time": 5.4, "name": "star-big" }, + { "time": 5.4667, "name": "star-medium" }, + { "time": 5.5333, "name": "star-small" }, + { "time": 5.6 }, + { "time": 6.0333, "name": "star-small" }, + { "time": 6.1, "name": "star-medium" }, + { "time": 6.1667, "name": "star-big" }, + { "time": 6.2333, "name": "star-medium" }, + { "time": 6.3, "name": "star-small" }, + { "time": 6.3667 }, + { "time": 7.2667, "name": "star-small" }, + { "time": 7.4, "name": "star-medium" }, + { "time": 7.5333, "name": "star-big" }, + { "time": 7.6667, "name": "star-medium" }, + { "time": 7.7333, "name": "star-small" }, + { "time": 7.8667 }, + { "time": 8.5, "name": "star-small" }, + { "time": 8.5667, "name": "star-medium" }, + { "time": 8.6333, "name": "star-big" }, + { "time": 8.7, "name": "star-medium" }, + { "time": 8.7333, "name": "star-small" }, + { "time": 8.8 }, + { "time": 9.2667, "name": "star-small" }, + { "time": 9.3333, "name": "star-medium" }, + { "time": 9.4, "name": "star-big" }, + { "time": 9.4667, "name": "star-medium" }, + { "time": 9.5333, "name": "star-small" }, + { "time": 9.6 } + ] + } + }, + "bones": { + "body-up": { + "rotate": [ + { + "time": 2.6333, + "curve": [ 2.822, 1.06, 3.011, 3.17 ] + }, + { "time": 3.2, "value": 3.17, "curve": "stepped" }, + { + "time": 9, + "value": 3.17, + "curve": [ 9.2, 3.17, 9.4, 1.06 ] + }, + { + "time": 9.6, + "curve": [ 9.611, -0.06, 9.622, 0 ] + }, + { "time": 9.6333 } + ], + "translate": [ + { + "curve": [ 0.311, -1.37, 0.624, 10, 0.311, 0, 0.624, 0 ] + }, + { + "time": 0.9333, + "x": 10, + "curve": [ 1.691, 10, 2.444, 0, 1.691, 0, 2.444, 0 ] + }, + { + "time": 3.2, + "curve": [ 3.509, 0, 3.824, 10, 3.509, 0, 3.824, 0 ] + }, + { + "time": 4.1333, + "x": 10, + "curve": [ 4.891, 10, 5.642, 3.33, 4.891, 0, 5.642, 0 ] + }, + { "time": 6.4, "curve": "stepped" }, + { + "time": 6.4333, + "curve": [ 6.743, 0, 7.057, 10, 6.743, 0, 7.057, 0 ] + }, + { + "time": 7.3667, + "x": 10, + "curve": [ 8.124, 10, 8.876, 3.33, 8.124, 0, 8.876, 0 ] + }, + { "time": 9.6333 } + ] + }, + "wing-front": { + "rotate": [ + { "time": 0.8333 }, + { "time": 1.7333, "value": -4.1 }, + { "time": 2.6667 }, + { "time": 3.0333, "value": -28.71 }, + { "time": 3.3667, "curve": "stepped" }, + { "time": 3.4667 }, + { "time": 4.0333, "value": -28.71 }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 5.8667, + "curve": [ 6.256, -1.37, 6.644, -4.1 ] + }, + { + "time": 7.0333, + "value": -4.1, + "curve": [ 7.478, -4.1, 7.922, -1.37 ] + }, + { "time": 8.3667 }, + { "time": 8.9333, "value": -28.71 }, + { "time": 9.6 } + ], + "scale": [ + { "time": 0.8333 }, + { "time": 1.7333, "y": 0.928 }, + { "time": 2.6667 }, + { "time": 3.0333, "y": 0.497 }, + { "time": 3.3667, "curve": "stepped" }, + { "time": 3.4667 }, + { "time": 4.0333, "y": 0.497 }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 5.8667, + "curve": [ 6.256, 1, 6.644, 1, 6.256, 0.976, 6.644, 0.928 ] + }, + { + "time": 7.0333, + "y": 0.928, + "curve": [ 7.478, 1, 7.922, 1, 7.478, 0.928, 7.922, 0.976 ] + }, + { "time": 8.3667 }, + { "time": 8.9333, "y": 0.497 }, + { "time": 9.6 } + ] + }, + "wing-front-tip": { + "rotate": [ + { "time": 0.9667 }, + { + "time": 2.0667, + "value": -7.42, + "curve": [ 2.097, -3.69, 2.451, -6.54 ] + }, + { "time": 2.6667 }, + { + "time": 2.8333, + "value": 33.17, + "curve": [ 2.891, 33.17, 2.916, 0 ] + }, + { + "time": 2.9667, + "curve": [ 3.029, 0, 3.128, -30.34 ] + }, + { + "time": 3.2, + "value": -30.34, + "curve": [ 3.258, -30.34, 3.317, 0 ] + }, + { "time": 3.3667, "curve": "stepped" }, + { "time": 3.4667 }, + { + "time": 3.6667, + "value": 33.17, + "curve": [ 3.755, 33.17, 3.824, 0 ] + }, + { + "time": 3.9333, + "curve": [ 4.067, 0, 4.245, -30.34 ] + }, + { + "time": 4.4, + "value": -30.34, + "curve": [ 4.525, -30.34, 4.631, 0 ] + }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 6.1333, + "curve": [ 6.522, -2.47, 7.24, -14.83 ] + }, + { + "time": 7.3, + "value": -7.42, + "curve": [ 7.331, -3.63, 7.969, -6.64 ] + }, + { "time": 8.3667 }, + { + "time": 8.6333, + "value": 33.17, + "curve": [ 8.731, 33.17, 8.78, 0 ] + }, + { + "time": 8.8667, + "curve": [ 8.973, 0, 9.144, -30.34 ] + }, + { + "time": 9.2667, + "value": -30.34, + "curve": [ 9.366, -30.34, 9.485, 0 ] + }, + { "time": 9.6 } + ] + }, + "wing-back-tip": { + "rotate": [ + { "time": 0.9667 }, + { + "time": 2.0667, + "value": 4.42, + "curve": [ 2.097, 2.2, 2.451, 3.9 ] + }, + { "time": 2.6667 }, + { + "time": 2.8667, + "value": -11.49, + "curve": [ 2.87, -11.49, 2.922, 0 ] + }, + { + "time": 2.9667, + "curve": [ 3.029, 0, 3.128, 18.1 ] + }, + { + "time": 3.2, + "value": 18.1, + "curve": [ 3.258, 18.1, 3.317, 0 ] + }, + { "time": 3.3667, "curve": "stepped" }, + { "time": 3.4667 }, + { + "time": 3.7, + "value": -11.49, + "curve": [ 3.705, -11.49, 3.837, 0 ] + }, + { + "time": 3.9333, + "curve": [ 4.067, 0, 4.245, 18.1 ] + }, + { + "time": 4.4, + "value": 18.1, + "curve": [ 4.525, 18.1, 4.631, 0 ] + }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 6.1333, + "curve": [ 6.522, 1.47, 7.24, 8.85 ] + }, + { + "time": 7.3, + "value": 4.42, + "curve": [ 7.331, 2.17, 7.969, 3.96 ] + }, + { "time": 8.3667 }, + { + "time": 8.6333, + "value": -11.49, + "curve": [ 8.639, -11.49, 8.79, 0 ] + }, + { + "time": 8.8667, + "curve": [ 8.973, 0, 9.144, 18.1 ] + }, + { + "time": 9.2667, + "value": 18.1, + "curve": [ 9.366, 18.1, 9.485, 0 ] + }, + { "time": 9.6 } + ], + "scale": [ + { "time": 0.9667 }, + { + "time": 2.0667, + "x": 1.043, + "curve": [ 2.096, 1.021, 2.451, 1, 2.096, 1, 2.451, 1 ] + }, + { + "time": 2.6667, + "curve": [ 2.718, 1, 2.816, 0.807, 2.718, 1, 2.816, 1 ] + }, + { + "time": 2.8667, + "x": 0.807, + "curve": [ 2.912, 0.807, 2.923, 1.061, 2.912, 1, 2.923, 1 ] + }, + { + "time": 2.9667, + "x": 1.081, + "curve": [ 3.037, 1.112, 3.131, 1.254, 3.037, 1, 3.131, 1 ] + }, + { + "time": 3.2, + "x": 1.222, + "curve": [ 3.254, 1.198, 3.317, 1, 3.254, 1, 3.317, 1 ] + }, + { "time": 3.3667, "curve": "stepped" }, + { + "time": 3.4667, + "curve": [ 3.545, 1, 3.623, 0.807, 3.545, 1, 3.623, 1 ] + }, + { + "time": 3.7, + "x": 0.807, + "curve": [ 3.769, 0.807, 3.84, 1.061, 3.769, 1, 3.84, 1 ] + }, + { + "time": 3.9333, + "x": 1.081, + "curve": [ 4.085, 1.112, 4.252, 1.254, 4.085, 1, 4.252, 1 ] + }, + { + "time": 4.4, + "x": 1.222, + "curve": [ 4.517, 1.198, 4.618, 1, 4.517, 1, 4.618, 1 ] + }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 6.1333, + "curve": [ 6.522, 1.014, 7.244, 1.085, 6.522, 1, 6.911, 1 ] + }, + { + "time": 7.3, + "x": 1.043, + "curve": [ 7.329, 1.02, 7.969, 1, 7.329, 1, 7.969, 1 ] + }, + { + "time": 8.3667, + "curve": [ 8.454, 1, 8.548, 0.807, 8.454, 1, 8.548, 1 ] + }, + { + "time": 8.6333, + "x": 0.807, + "curve": [ 8.71, 0.807, 8.793, 1.061, 8.71, 1, 8.793, 1 ] + }, + { + "time": 8.8667, + "x": 1.081, + "curve": [ 8.987, 1.112, 9.149, 1.254, 8.987, 1, 9.149, 1 ] + }, + { + "time": 9.2667, + "x": 1.222, + "curve": [ 9.359, 1.198, 9.47, 1, 9.359, 1, 9.47, 1 ] + }, + { "time": 9.6 } + ] + }, + "wing-back": { + "rotate": [ + { "time": 0.8333 }, + { + "time": 1.9333, + "value": 1.94, + "curve": [ 1.967, 0.82, 2.422, 0 ] + }, + { + "time": 2.6667, + "curve": [ 2.778, 0, 2.922, 31.82 ] + }, + { + "time": 3.0333, + "value": 31.82, + "curve": [ 3.141, 31.82, 3.254, 0 ] + }, + { "time": 3.3667, "curve": "stepped" }, + { + "time": 3.4667, + "curve": [ 3.637, 0, 3.795, 31.82 ] + }, + { + "time": 4.0333, + "value": 31.82, + "curve": [ 4.265, 31.82, 4.502, 0 ] + }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 5.8667, + "curve": [ 6.256, 0.65, 6.975, 3.88 ] + }, + { + "time": 7.0333, + "value": 1.94, + "curve": [ 7.067, 0.82, 7.922, 0 ] + }, + { + "time": 8.3667, + "curve": [ 8.556, 0, 8.744, 31.82 ] + }, + { + "time": 8.9333, + "value": 31.82, + "curve": [ 9.117, 31.82, 9.34, 0 ] + }, + { "time": 9.6 } + ], + "scale": [ + { "time": 0.8333 }, + { + "time": 1.9333, + "x": 1.015, + "y": 0.962, + "curve": [ 1.967, 1.006, 2.422, 1, 1.967, 0.984, 2.422, 1 ] + }, + { + "time": 2.6667, + "curve": [ 2.778, 1, 2.922, 1.248, 2.778, 1, 2.922, 0.376 ] + }, + { + "time": 3.0333, + "x": 1.248, + "y": 0.376, + "curve": [ 3.141, 1.248, 3.254, 1, 3.141, 0.376, 3.254, 1 ] + }, + { "time": 3.3667, "curve": "stepped" }, + { + "time": 3.4667, + "curve": [ 3.637, 1, 3.795, 1.248, 3.637, 1, 3.795, 0.376 ] + }, + { + "time": 4.0333, + "x": 1.248, + "y": 0.376, + "curve": [ 4.265, 1.248, 4.502, 1, 4.265, 0.376, 4.502, 1 ] + }, + { "time": 4.7333, "curve": "stepped" }, + { + "time": 5.8667, + "curve": [ 6.256, 1.005, 6.975, 1.03, 6.256, 0.987, 6.975, 0.924 ] + }, + { + "time": 7.0333, + "x": 1.015, + "y": 0.962, + "curve": [ 7.067, 1.006, 7.922, 1, 7.067, 0.984, 7.922, 1 ] + }, + { + "time": 8.3667, + "curve": [ 8.556, 1, 8.744, 1.248, 8.556, 1, 8.744, 0.376 ] + }, + { + "time": 8.9333, + "x": 1.248, + "y": 0.376, + "curve": [ 9.117, 1.248, 9.34, 1, 9.117, 0.376, 9.34, 1 ] + }, + { "time": 9.6 } + ] + }, + "pupil-front": { + "translate": [ + { + "x": -9.97, + "curve": [ 0.033, -9.97, 0.067, -6.11, 0.033, 0, 0.067, 0 ] + }, + { + "time": 0.1, + "x": -6.11, + "curve": [ 0.282, -6.11, 0.256, -9.97, 0.183, 0, 0.256, 0 ] + }, + { "time": 0.3333, "x": -9.97, "curve": "stepped" }, + { "time": 1.4333, "x": -9.97 }, + { "time": 1.6333, "x": -9.97, "y": 5.36, "curve": "stepped" }, + { "time": 6.4667, "x": -9.97, "y": 5.36 }, + { "time": 6.7667, "x": -9.97 } + ], + "scale": [ + { + "curve": [ 0.033, 1, 0.071, 0.152, 0.033, 1, 0.071, 1 ] + }, + { + "time": 0.1, + "x": 0.152, + "curve": [ 0.282, 0.152, 0.244, 1, 0.183, 1, 0.25, 1 ] + }, + { "time": 0.3333 } + ] + }, + "pupil-back": { + "translate": [ + { + "x": -8.93, + "curve": [ 0.033, -8.93, 0.067, -6.11, 0.033, 0, 0.067, 0 ] + }, + { + "time": 0.1, + "x": -6.11, + "curve": [ 0.282, -6.11, 0.256, -8.93, 0.183, 0, 0.256, 0 ] + }, + { "time": 0.3333, "x": -8.93, "curve": "stepped" }, + { "time": 1.4333, "x": -8.93 }, + { "time": 1.6333, "x": -8.93, "y": 3.83, "curve": "stepped" }, + { "time": 6.4667, "x": -8.93, "y": 3.83 }, + { "time": 6.7667, "x": -8.93 } + ], + "scale": [ + { + "curve": [ 0.033, 1, 0.071, 0.152, 0.033, 1, 0.071, 1 ] + }, + { + "time": 0.1, + "x": 0.152, + "curve": [ 0.282, 0.152, 0.244, 1, 0.183, 1, 0.25, 1 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-top-front": { + "translate": [ + { + "x": -15.36, + "y": 1.57, + "curve": [ 0.033, -15.36, 0.067, -26.84, 0.033, 1.57, 0.067, 0 ] + }, + { + "time": 0.1, + "x": -26.84, + "curve": [ 0.282, -26.84, 0.256, -10.38, 0.183, 0, 0.256, 1.06 ] + }, + { "time": 0.3333, "x": -10.38, "y": 1.06, "curve": "stepped" }, + { "time": 8.3667, "x": -10.38, "y": 1.06 }, + { "time": 8.8667, "x": -15.36, "y": 1.57 } + ] + }, + "eyelashes-top-back": { + "translate": [ + { + "x": -14.46, + "y": -3.29, + "curve": [ 0.033, -14.46, 0.067, -22.55, 0.033, -3.29, 0.067, 0 ] + }, + { + "time": 0.1, + "x": -22.55, + "curve": [ 0.282, -22.55, 0.256, -9.45, 0.183, 0, 0.256, -3.29 ] + }, + { "time": 0.3333, "x": -9.45, "y": -3.29, "curve": "stepped" }, + { "time": 8.3667, "x": -9.45, "y": -3.29 }, + { "time": 8.8667, "x": -14.46, "y": -3.29 } + ] + }, + "face-control": { + "translate": [ + { "x": -2.21, "curve": "stepped" }, + { "time": 1.4, "x": -2.21 }, + { "time": 1.8333, "x": -2.21, "y": 11.22 }, + { "time": 2.6, "x": -2.21, "y": 12.66 }, + { "time": 2.8667, "x": -6.06, "y": 13.01 }, + { "time": 3.3, "x": -2.21, "y": 13.4 }, + { "time": 6.6333, "x": -2.21, "y": 11.22 }, + { "time": 6.8, "x": -5.12, "y": 4.99 }, + { "time": 6.9333, "x": -2.21 } + ] + }, + "face": { + "rotate": [ + { "value": -15.25, "curve": "stepped" }, + { + "time": 2.5, + "value": -15.25, + "curve": [ 2.744, -13.13, 2.989, -8.89 ] + }, + { "time": 3.2333, "value": -8.89, "curve": "stepped" }, + { + "time": 8.2, + "value": -8.89, + "curve": [ 8.544, -8.89, 8.889, -15.25 ] + }, + { "time": 9.2333, "value": -15.25 } + ] + }, + "hair-back": { + "rotate": [ + { "value": 12.31, "curve": "stepped" }, + { "time": 2.5, "value": 12.31 }, + { "time": 3.2, "value": 7.32, "curve": "stepped" }, + { "time": 8.5333, "value": 7.32 }, + { "time": 9.5667, "value": 12.31 } + ] + }, + "fringe-side-front": { + "rotate": [ + { "value": 6.43, "curve": "stepped" }, + { "time": 2.5, "value": 6.43 }, + { "time": 3.2, "value": 6.92, "curve": "stepped" }, + { "time": 8.5333, "value": 6.92 }, + { "time": 9.5667, "value": 6.43 } + ] + }, + "fringe-side-back": { + "rotate": [ + { "value": 6.43, "curve": "stepped" }, + { "time": 2.5, "value": 6.43 }, + { "time": 3.2, "value": 6.92, "curve": "stepped" }, + { "time": 8.5333, "value": 6.92 }, + { "time": 9.5667, "value": 6.43 } + ] + }, + "leg-front-down": { + "rotate": [ + { "value": -25.69, "curve": "stepped" }, + { + "time": 2.6333, + "value": -25.69, + "curve": [ 2.967, -22.72, 3.3, -16.78 ] + }, + { "time": 3.6333, "value": -16.78, "curve": "stepped" }, + { + "time": 7.3667, + "value": -16.78, + "curve": [ 7.689, -16.78, 8.011, -22.72 ] + }, + { + "time": 8.3333, + "value": -25.69, + "curve": [ 8.767, -29.68, 9.2, -25.69 ] + }, + { "time": 9.6333, "value": -25.69 } + ] + }, + "leg-back-down": { + "rotate": [ + { "value": -31.75 } + ] + }, + "eyelashes-down-front": { + "translate": [ + { + "curve": [ 0.033, 0, 0.071, 12.12, 0.033, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": 12.12, + "curve": [ 0.282, 12.12, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ] + }, + "eyelashes-down-back": { + "translate": [ + { + "curve": [ 0.033, 0, 0.071, 10.12, 0.033, 0, 0.071, 0 ] + }, + { + "time": 0.1, + "x": 10.12, + "curve": [ 0.282, 10.12, 0.244, 0, 0.183, 0, 0.25, 0 ] + }, + { "time": 0.3333 } + ] + }, + "swing-top": { + "rotate": [ + { + "curve": [ 0.244, 0, 0.489, 0 ] + }, + { + "time": 0.7333, + "value": -0.11, + "curve": [ 0.989, -0.23, 1.244, -1.74 ] + }, + { + "time": 1.5, + "value": -1.74, + "curve": [ 1.744, -1.74, 1.989, 0.52 ] + }, + { + "time": 2.2333, + "value": 0.52, + "curve": [ 2.389, 0.52, 2.544, -0.61 ] + }, + { + "time": 2.7, + "value": -0.61, + "curve": [ 2.9, -0.61, 3.1, 1.19 ] + }, + { + "time": 3.3, + "value": 1.19, + "curve": [ 3.522, 1.19, 3.744, 1.19 ] + }, + { + "time": 3.9667, + "value": 0.66, + "curve": [ 4.344, -0.24, 4.722, -3.51 ] + }, + { + "time": 5.1, + "value": -3.51, + "curve": [ 5.211, -3.51, 5.322, -3.39 ] + }, + { + "time": 5.4333, + "value": -3.26, + "curve": [ 5.644, -3, 5.856, -2.71 ] + }, + { + "time": 6.0667, + "value": -2.32, + "curve": [ 6.356, -1.77, 6.644, -0.44 ] + }, + { + "time": 6.9333, + "value": -0.44, + "curve": [ 7.111, -0.44, 7.289, -0.82 ] + }, + { + "time": 7.4667, + "value": -0.82, + "curve": [ 7.811, -0.82, 8.156, 4.18 ] + }, + { + "time": 8.5, + "value": 4.18, + "curve": [ 8.867, 4.18, 9.233, 1.39 ] + }, + { + "time": 9.6, + "curve": [ 9.611, -0.04, 9.622, 0 ] + }, + { "time": 9.6333 } + ] + }, + "cloud": { + "translate": [ + { + "curve": [ 0.356, 0, 0.711, -11.64, 0.356, 0, 0.711, 0 ] + }, + { + "time": 1.0667, + "x": -11.64, + "curve": [ 1.5, -11.64, 1.933, 17.3, 1.5, 0, 1.933, 0 ] + }, + { + "time": 2.3667, + "x": 17.3, + "curve": [ 2.944, 17.3, 3.522, 17.3, 2.944, 0, 3.522, 0 ] + }, + { + "time": 4.1, + "x": 13.15, + "curve": [ 4.444, 10.68, 4.789, -11.93, 4.444, 0, 4.789, 0 ] + }, + { + "time": 5.1333, + "x": -12.61, + "curve": [ 5.878, -14.07, 6.622, -14.07, 5.878, 0, 6.622, 0 ] + }, + { + "time": 7.3667, + "x": -14.07, + "curve": [ 7.689, -14.07, 8.011, 19.19, 7.689, 0, 8.011, 0 ] + }, + { + "time": 8.3333, + "x": 19.19, + "curve": [ 8.756, 19.19, 9.178, 6.4, 8.756, 0, 9.178, 0 ] + }, + { + "time": 9.6, + "curve": [ 9.611, -0.17, 9.622, 0, 9.611, 0, 9.622, 0 ] + }, + { "time": 9.6333 } + ] + }, + "arm-front-up-holder": { + "translate": [ + { "time": 2 }, + { "time": 3.6667, "x": -1.79, "y": -23.94, "curve": "stepped" }, + { "time": 7.8667, "x": -1.79, "y": -23.94 }, + { "time": 9.0667 } + ] + }, + "bench-back": { + "translate": [ + { + "x": 8.04, + "curve": [ 0.156, 8.04, 0.311, 0, 0.156, 0, 0.311, 0 ] + }, + { + "time": 0.4667, + "curve": [ 0.822, 0, 1.178, -11.64, 0.822, 0, 1.178, 0 ] + }, + { + "time": 1.5333, + "x": -11.64, + "curve": [ 1.967, -11.64, 2.4, 17.3, 1.967, 0, 2.4, 0 ] + }, + { + "time": 2.8333, + "x": 17.3, + "curve": [ 3.411, 17.3, 3.989, 17.3, 3.411, 0, 3.989, 0 ] + }, + { + "time": 4.5667, + "x": 13.15, + "curve": [ 4.911, 10.68, 5.256, -11.93, 4.911, 0, 5.256, 0 ] + }, + { + "time": 5.6, + "x": -12.61, + "curve": [ 6.344, -14.07, 7.089, -14.07, 6.344, 0, 7.089, 0 ] + }, + { + "time": 7.8333, + "x": -14.07, + "curve": [ 8.156, -14.07, 8.478, 19.19, 8.156, 0, 8.478, 0 ] + }, + { + "time": 8.8, + "x": 19.19, + "curve": [ 9.079, 19.19, 9.267, 8.04, 9.079, 0, 9.357, 0 ] + }, + { "time": 9.6333, "x": 8.04 } + ] + } + }, + "physics": { + "girl/feathers-front": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "girl/feathers-front-top": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "girl/hair/fringe-side-back": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "girl/hair/fringe-side-front": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "girl/hair/hair-back": { + "wind": [ + { + "value": -4.3, + "curve": [ 0.189, -4.3, 0.378, -14.3 ] + }, + { + "time": 0.5667, + "value": -14.3, + "curve": [ 0.911, -14.3, 1.256, -6.3803 ] + }, + { + "time": 1.6, + "value": -4.3, + "curve": [ 2.1, -1.2803, 2.6, 1 ] + }, + { + "time": 3.1, + "value": 1, + "curve": [ 3.578, 1, 4.056, 1 ] + }, + { + "time": 4.5333, + "curve": [ 4.822, -0.6047, 5.111, -10 ] + }, + { + "time": 5.4, + "value": -10, + "curve": [ 5.667, -10, 5.933, -5 ] + }, + { + "time": 6.2, + "value": -5, + "curve": [ 6.389, -5, 6.578, -7 ] + }, + { + "time": 6.7667, + "value": -7, + "curve": [ 7.178, -7, 7.589, -2.9126 ] + }, + { + "time": 8, + "value": 1, + "curve": [ 8.233, 3.2207, 8.467, 11.4 ] + }, + { + "time": 8.7, + "value": 11.4, + "curve": [ 8.967, 11.4, 9.233, -4.3 ] + }, + { "time": 9.5, "value": -4.3 } + ] + }, + "girl/legs/sock-bow": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "girl/skirt/skirt-back": { + "wind": [ + {}, + { "time": 0.6, "value": -8.6 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.4 }, + { "time": 5, "value": -7.1, "curve": "stepped" }, + { "time": 6.6333, "value": -7.1 }, + { "time": 8.4333, "value": 7.1 }, + { "time": 9.6 } + ] + }, + "girl/skirt/skirt-front": { + "wind": [ + {}, + { "time": 0.7333, "value": -8.6 }, + { "time": 1.6667, "curve": "stepped" }, + { "time": 4.5333 }, + { "time": 5.1333, "value": -7.1, "curve": "stepped" }, + { "time": 6.8667, "value": -7.1 }, + { "time": 8.2333, "value": 7.1 }, + { "time": 9.6 } + ] + }, + "girl/wings/wing-back": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "girl/wings/wing-front": { + "wind": [ + { "value": -15.8 }, + { "time": 0.7667, "value": -33.3 }, + { "time": 1.5333, "curve": "stepped" }, + { "time": 4.9 }, + { "time": 5.5, "value": -19.3 }, + { "time": 5.9667, "value": -5.7 }, + { "time": 6.8, "value": -15.7 }, + { "time": 7.9333 }, + { "time": 8.7667, "value": 8.6 }, + { "time": 9.6333, "value": -15.8 } + ] + }, + "": { + "wind": [ + { + "value": -15.8, + "curve": [ 0.256, -15.8, 0.511, -33.3 ] + }, + { + "time": 0.7667, + "value": -33.3, + "curve": [ 1.044, -33.3, 1.322, 0 ] + }, + { + "time": 1.6, + "curve": [ 1.8, 0, 2, -8.6 ] + }, + { + "time": 2.2, + "value": -8.6, + "curve": [ 2.5, -8.6, 2.8, 1 ] + }, + { + "time": 3.1, + "value": 1, + "curve": [ 3.578, 1, 4.056, 0 ] + }, + { "time": 4.5333, "curve": "stepped" }, + { + "time": 4.9, + "curve": [ 5.1, 0, 5.3, -19.3 ] + }, + { + "time": 5.5, + "value": -19.3, + "curve": [ 5.656, -19.3, 5.811, -7.1 ] + }, + { + "time": 5.9667, + "value": -5.7, + "curve": [ 6.044, -5, 6.122, -5 ] + }, + { + "time": 6.2, + "value": -5, + "curve": [ 6.389, -5, 6.578, -7 ] + }, + { + "time": 6.7667, + "value": -7, + "curve": [ 7.156, -7, 7.544, -3.7011 ] + }, + { + "time": 7.9333, + "curve": [ 8.189, 2.4322, 8.444, 11.4 ] + }, + { + "time": 8.7, + "value": 11.4, + "curve": [ 9.011, 11.4, 9.322, -15.8 ] + }, + { "time": 9.6333, "value": -15.8 } + ] + } + } + }, + "wing-flap": { + "bones": { + "body-up": { + "translate": [ + { + "curve": [ 0.222, 0, 0.444, 10, 0.222, 0, 0.444, 0 ] + }, + { + "time": 0.6667, + "x": 10, + "curve": [ 1.211, 10, 1.756, 3.33, 1.211, 0, 1.756, 0 ] + }, + { "time": 2.3 } + ] + }, + "wing-front": { + "rotate": [ + {}, + { "time": 0.6, "value": -28.71 }, + { "time": 1.1333 }, + { "time": 1.7, "value": -28.71 }, + { "time": 2.2667 } + ], + "scale": [ + {}, + { "time": 0.6, "y": 0.497 }, + { "time": 1.1333 }, + { "time": 1.7, "y": 0.497 }, + { "time": 2.2667 } + ] + }, + "wing-front-tip": { + "rotate": [ + {}, + { + "time": 0.2333, + "value": 33.17, + "curve": [ 0.333, 33.17, 0.412, 0 ] + }, + { + "time": 0.5, + "curve": [ 0.608, 0, 0.742, -30.34 ] + }, + { + "time": 0.8667, + "value": -30.34, + "curve": [ 0.968, -30.34, 1.042, -12.9 ] + }, + { "time": 1.1333 }, + { + "time": 1.3667, + "value": 33.17, + "curve": [ 1.466, 33.17, 1.545, 0 ] + }, + { + "time": 1.6333, + "curve": [ 1.741, 0, 1.875, -30.34 ] + }, + { + "time": 2, + "value": -30.34, + "curve": [ 2.101, -30.34, 2.184, 0 ] + }, + { "time": 2.2667 } + ] + }, + "wing-back-tip": { + "rotate": [ + {}, + { + "time": 0.2667, + "value": -11.49, + "curve": [ 0.272, -11.49, 0.422, 0 ] + }, + { + "time": 0.5, + "curve": [ 0.608, 0, 0.742, 18.1 ] + }, + { + "time": 0.8667, + "value": 18.1, + "curve": [ 0.968, 18.1, 1.042, 3.83 ] + }, + { "time": 1.1333 }, + { + "time": 1.4, + "value": -11.49, + "curve": [ 1.406, -11.49, 1.555, 0 ] + }, + { + "time": 1.6333, + "curve": [ 1.741, 0, 1.875, 18.1 ] + }, + { + "time": 2, + "value": 18.1, + "curve": [ 2.101, 18.1, 2.184, 0 ] + }, + { "time": 2.2667 } + ], + "scale": [ + { + "curve": [ 0.089, 1, 0.18, 0.807, 0.089, 1, 0.18, 1 ] + }, + { + "time": 0.2667, + "x": 0.807, + "curve": [ 0.345, 0.807, 0.425, 1.061, 0.345, 1, 0.425, 1 ] + }, + { + "time": 0.5, + "x": 1.081, + "curve": [ 0.622, 1.112, 0.747, 1.254, 0.622, 1, 0.747, 1 ] + }, + { + "time": 0.8667, + "x": 1.222, + "curve": [ 0.961, 1.198, 1.042, 1, 0.961, 1, 1.042, 1 ] + }, + { + "time": 1.1333, + "curve": [ 1.222, 1, 1.313, 0.807, 1.222, 1, 1.313, 1 ] + }, + { + "time": 1.4, + "x": 0.807, + "curve": [ 1.478, 0.807, 1.558, 1.061, 1.478, 1, 1.558, 1 ] + }, + { + "time": 1.6333, + "x": 1.081, + "curve": [ 1.755, 1.112, 1.88, 1.254, 1.755, 1, 1.88, 1 ] + }, + { + "time": 2, + "x": 1.222, + "curve": [ 2.094, 1.198, 2.173, 1, 2.094, 1, 2.173, 1 ] + }, + { "time": 2.2667 } + ] + }, + "wing-back": { + "rotate": [ + { + "curve": [ 0.193, 0, 0.407, 31.82 ] + }, + { + "time": 0.6, + "value": 31.82, + "curve": [ 0.787, 31.82, 0.951, 0 ] + }, + { + "time": 1.1333, + "curve": [ 1.326, 0, 1.507, 31.82 ] + }, + { + "time": 1.7, + "value": 31.82, + "curve": [ 1.887, 31.82, 2.08, 0 ] + }, + { "time": 2.2667 } + ], + "scale": [ + { + "curve": [ 0.193, 1, 0.407, 1.248, 0.193, 1, 0.407, 0.376 ] + }, + { + "time": 0.6, + "x": 1.248, + "y": 0.376, + "curve": [ 0.787, 1.248, 0.951, 1, 0.787, 0.376, 0.951, 1 ] + }, + { + "time": 1.1333, + "curve": [ 1.326, 1, 1.507, 1.248, 1.326, 1, 1.507, 0.376 ] + }, + { + "time": 1.7, + "x": 1.248, + "y": 0.376, + "curve": [ 1.887, 1.248, 2.08, 1, 1.887, 0.376, 2.08, 1 ] + }, + { "time": 2.2667 } + ] + } + } + }, + "wings-and-feet": { + "bones": { + "body-up": { + "translate": [ + { + "curve": [ 0.222, 0, 0.444, 10, 0.222, 0, 0.444, 0 ] + }, + { + "time": 0.6667, + "x": 10, + "curve": [ 1.211, 10, 1.756, 3.33, 1.211, 0, 1.756, 0 ] + }, + { "time": 2.3 } + ] + }, + "wing-front": { + "rotate": [ + {}, + { "time": 0.6, "value": -28.71 }, + { "time": 1.1333 }, + { "time": 1.7, "value": -28.71 }, + { "time": 2.2667 } + ], + "scale": [ + {}, + { "time": 0.6, "y": 0.497 }, + { "time": 1.1333 }, + { "time": 1.7, "y": 0.497 }, + { "time": 2.2667 } + ] + }, + "wing-front-tip": { + "rotate": [ + {}, + { + "time": 0.2333, + "value": 33.17, + "curve": [ 0.333, 33.17, 0.412, 0 ] + }, + { + "time": 0.5, + "curve": [ 0.608, 0, 0.742, -30.34 ] + }, + { + "time": 0.8667, + "value": -30.34, + "curve": [ 0.968, -30.34, 1.042, -12.9 ] + }, + { "time": 1.1333 }, + { + "time": 1.3667, + "value": 33.17, + "curve": [ 1.466, 33.17, 1.545, 0 ] + }, + { + "time": 1.6333, + "curve": [ 1.741, 0, 1.875, -30.34 ] + }, + { + "time": 2, + "value": -30.34, + "curve": [ 2.101, -30.34, 2.184, 0 ] + }, + { "time": 2.2667 } + ] + }, + "wing-back-tip": { + "rotate": [ + {}, + { + "time": 0.2667, + "value": -11.49, + "curve": [ 0.272, -11.49, 0.422, 0 ] + }, + { + "time": 0.5, + "curve": [ 0.608, 0, 0.742, 18.1 ] + }, + { + "time": 0.8667, + "value": 18.1, + "curve": [ 0.968, 18.1, 1.042, 3.83 ] + }, + { "time": 1.1333 }, + { + "time": 1.4, + "value": -11.49, + "curve": [ 1.406, -11.49, 1.555, 0 ] + }, + { + "time": 1.6333, + "curve": [ 1.741, 0, 1.875, 18.1 ] + }, + { + "time": 2, + "value": 18.1, + "curve": [ 2.101, 18.1, 2.184, 0 ] + }, + { "time": 2.2667 } + ], + "scale": [ + { + "curve": [ 0.089, 1, 0.18, 0.807, 0.089, 1, 0.18, 1 ] + }, + { + "time": 0.2667, + "x": 0.807, + "curve": [ 0.345, 0.807, 0.425, 1.061, 0.345, 1, 0.425, 1 ] + }, + { + "time": 0.5, + "x": 1.081, + "curve": [ 0.622, 1.112, 0.747, 1.254, 0.622, 1, 0.747, 1 ] + }, + { + "time": 0.8667, + "x": 1.222, + "curve": [ 0.961, 1.198, 1.042, 1, 0.961, 1, 1.042, 1 ] + }, + { + "time": 1.1333, + "curve": [ 1.222, 1, 1.313, 0.807, 1.222, 1, 1.313, 1 ] + }, + { + "time": 1.4, + "x": 0.807, + "curve": [ 1.478, 0.807, 1.558, 1.061, 1.478, 1, 1.558, 1 ] + }, + { + "time": 1.6333, + "x": 1.081, + "curve": [ 1.755, 1.112, 1.88, 1.254, 1.755, 1, 1.88, 1 ] + }, + { + "time": 2, + "x": 1.222, + "curve": [ 2.094, 1.198, 2.173, 1, 2.094, 1, 2.173, 1 ] + }, + { "time": 2.2667 } + ] + }, + "wing-back": { + "rotate": [ + { + "curve": [ 0.193, 0, 0.407, 31.82 ] + }, + { + "time": 0.6, + "value": 31.82, + "curve": [ 0.787, 31.82, 0.951, 0 ] + }, + { + "time": 1.1333, + "curve": [ 1.326, 0, 1.507, 31.82 ] + }, + { + "time": 1.7, + "value": 31.82, + "curve": [ 1.887, 31.82, 2.08, 0 ] + }, + { "time": 2.2667 } + ], + "scale": [ + { + "curve": [ 0.193, 1, 0.407, 1.248, 0.193, 1, 0.407, 0.376 ] + }, + { + "time": 0.6, + "x": 1.248, + "y": 0.376, + "curve": [ 0.787, 1.248, 0.951, 1, 0.787, 0.376, 0.951, 1 ] + }, + { + "time": 1.1333, + "curve": [ 1.326, 1, 1.507, 1.248, 1.326, 1, 1.507, 0.376 ] + }, + { + "time": 1.7, + "x": 1.248, + "y": 0.376, + "curve": [ 1.887, 1.248, 2.08, 1, 1.887, 0.376, 2.08, 1 ] + }, + { "time": 2.2667 } + ] + }, + "leg-back-down": { + "rotate": [ + { + "value": -15.56, + "curve": [ 0.122, -7.02, 0.244, 8.91 ] + }, + { + "time": 0.3667, + "value": 8.91, + "curve": [ 0.556, 8.91, 0.744, -26.59 ] + }, + { + "time": 0.9333, + "value": -26.59, + "curve": [ 1.133, -26.59, 1.333, 8.91 ] + }, + { + "time": 1.5333, + "value": 8.91, + "curve": [ 1.744, 8.91, 1.956, -20.89 ] + }, + { + "time": 2.1667, + "value": -20.89, + "curve": [ 2.211, -20.89, 2.256, -18.67 ] + }, + { "time": 2.3, "value": -15.56 } + ] + }, + "leg-front-down": { + "rotate": [ + { + "value": 8.91, + "curve": [ 0.189, 8.91, 0.378, -26.59 ] + }, + { + "time": 0.5667, + "value": -26.59, + "curve": [ 0.767, -26.59, 0.967, 8.91 ] + }, + { + "time": 1.1667, + "value": 8.91, + "curve": [ 1.378, 8.91, 1.589, -20.89 ] + }, + { + "time": 1.8, + "value": -20.89, + "curve": [ 1.967, -20.89, 2.133, 8.91 ] + }, + { "time": 2.3, "value": 8.91 } + ] + } + } + } +} +} \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/example/assets/celestial-circus.atlas b/spine-ts/spine-canvaskit/example/assets/celestial-circus.atlas new file mode 100644 index 000000000..17f32b2a3 --- /dev/null +++ b/spine-ts/spine-canvaskit/example/assets/celestial-circus.atlas @@ -0,0 +1,173 @@ +celestial-circus.png + size: 1024, 1024 + filter: Linear, Linear + scale: 0.4 +arm-back-down + bounds: 324, 401, 38, 82 + rotate: 90 +arm-back-up + bounds: 290, 44, 83, 116 + rotate: 90 +arm-front-down + bounds: 706, 2, 36, 78 + rotate: 90 +arm-front-up + bounds: 860, 138, 77, 116 +bench + bounds: 725, 256, 189, 48 +body-bottom + bounds: 879, 868, 154, 124 + rotate: 90 +body-top + bounds: 725, 128, 126, 133 + rotate: 90 +chest + bounds: 408, 26, 104, 93 +cloud-back + bounds: 752, 378, 202, 165 +cloud-front + bounds: 2, 2, 325, 196 + rotate: 90 +collar + bounds: 786, 13, 47, 26 +ear + bounds: 1002, 643, 20, 28 +eye-back-shadow + bounds: 428, 395, 14, 10 +eye-front-shadow + bounds: 704, 529, 24, 14 +eye-reflex-back + bounds: 860, 128, 8, 7 + rotate: 90 +eye-reflex-front + bounds: 726, 386, 10, 7 +eye-white-back + bounds: 835, 23, 13, 16 +eye-white-front + bounds: 1005, 1000, 22, 17 + rotate: 90 +eyelashes-down-back + bounds: 232, 329, 11, 6 + rotate: 90 +eyelashes-down-front + bounds: 913, 851, 15, 6 + rotate: 90 +eyelashes-top-back + bounds: 408, 395, 18, 10 +eyelashes-top-front + bounds: 702, 179, 30, 16 + rotate: 90 +face + bounds: 514, 26, 93, 102 + rotate: 90 +feathers-back + bounds: 954, 625, 46, 46 +feathers-front + bounds: 706, 40, 72, 86 +fringe-middle-back + bounds: 200, 6, 33, 52 + rotate: 90 +fringe-middle-front + bounds: 878, 76, 60, 50 + rotate: 90 +fringe-side-back + bounds: 780, 41, 27, 94 + rotate: 90 +fringe-side-front + bounds: 939, 161, 26, 93 +glove-bottom-back + bounds: 954, 572, 51, 41 + rotate: 90 +glove-bottom-front + bounds: 916, 256, 47, 48 +hair-back-1 + bounds: 444, 395, 132, 306 + rotate: 90 +hair-back-2 + bounds: 438, 211, 80, 285 + rotate: 90 +hair-back-3 + bounds: 719, 306, 70, 268 + rotate: 90 +hair-back-4 + bounds: 438, 121, 88, 262 + rotate: 90 +hair-back-5 + bounds: 438, 293, 88, 279 + rotate: 90 +hair-back-6 + bounds: 200, 41, 88, 286 +hair-hat-shadow + bounds: 232, 398, 90, 41 +hand-back + bounds: 954, 673, 60, 47 + rotate: 90 +hand-front + bounds: 967, 172, 53, 60 +hat-back + bounds: 954, 802, 64, 45 + rotate: 90 +hat-front + bounds: 780, 70, 96, 56 +head-back + bounds: 618, 17, 102, 86 + rotate: 90 +jabot + bounds: 967, 234, 70, 55 + rotate: 90 +leg-back + bounds: 232, 441, 210, 333 +leg-front + bounds: 444, 529, 258, 320 +logo-brooch + bounds: 954, 545, 16, 25 +mouth + bounds: 408, 121, 22, 6 +neck + bounds: 232, 342, 39, 56 + rotate: 90 +nose + bounds: 742, 529, 6, 7 + rotate: 90 +nose-highlight + bounds: 719, 300, 4, 4 +nose-shadow + bounds: 869, 128, 7, 8 +pupil-back + bounds: 730, 529, 10, 14 +pupil-front + bounds: 254, 21, 12, 18 +rope-back + bounds: 232, 383, 10, 492 + rotate: 90 +rope-front + bounds: 232, 383, 10, 492 + rotate: 90 +rope-front-bottom + bounds: 954, 735, 42, 65 +skirt + bounds: 2, 776, 440, 246 +sock-bow + bounds: 408, 407, 33, 32 +spine-logo-body + bounds: 879, 853, 13, 32 + rotate: 90 +star-big + bounds: 939, 141, 18, 24 + rotate: 90 +star-medium + bounds: 742, 537, 6, 8 + rotate: 90 +star-small + bounds: 719, 378, 3, 4 + rotate: 90 +underskirt + bounds: 2, 329, 445, 228 + rotate: 90 +underskirt-back + bounds: 444, 851, 433, 171 +wing-back + bounds: 290, 129, 146, 252 +wing-front + bounds: 704, 545, 304, 248 + rotate: 90 diff --git a/spine-ts/spine-canvaskit/example/assets/celestial-circus.png b/spine-ts/spine-canvaskit/example/assets/celestial-circus.png new file mode 100644 index 000000000..a5c26ccf2 Binary files /dev/null and b/spine-ts/spine-canvaskit/example/assets/celestial-circus.png differ diff --git a/spine-ts/spine-canvaskit/example/assets/mix-and-match-pro.skel b/spine-ts/spine-canvaskit/example/assets/mix-and-match-pro.skel new file mode 100644 index 000000000..afe6d4738 Binary files /dev/null and b/spine-ts/spine-canvaskit/example/assets/mix-and-match-pro.skel differ diff --git a/spine-ts/spine-canvaskit/example/assets/mix-and-match.atlas b/spine-ts/spine-canvaskit/example/assets/mix-and-match.atlas new file mode 100644 index 000000000..b8047722c --- /dev/null +++ b/spine-ts/spine-canvaskit/example/assets/mix-and-match.atlas @@ -0,0 +1,358 @@ +mix-and-match.png + size: 1024, 512 + filter: Linear, Linear + scale: 0.5 +base-head + bounds: 118, 70, 95, 73 +boy/arm-front + bounds: 831, 311, 36, 115 + rotate: 90 +boy/backpack + bounds: 249, 357, 119, 153 +boy/backpack-pocket + bounds: 628, 193, 34, 62 + rotate: 90 +boy/backpack-strap-front + bounds: 330, 263, 38, 88 + rotate: 90 +boy/backpack-up + bounds: 482, 171, 21, 70 +boy/body + bounds: 845, 413, 97, 132 + rotate: 90 +boy/boot-ribbon-front + bounds: 234, 304, 9, 11 +boy/collar + bounds: 471, 243, 73, 29 + rotate: 90 +boy/ear + bounds: 991, 352, 19, 23 + rotate: 90 +boy/eye-back-low-eyelid + bounds: 66, 72, 17, 6 +boy/eye-back-pupil + bounds: 694, 279, 8, 9 + rotate: 90 +boy/eye-back-up-eyelid + bounds: 460, 101, 23, 5 + rotate: 90 +boy/eye-back-up-eyelid-back + bounds: 979, 414, 19, 10 + rotate: 90 +boy/eye-front-low-eyelid + bounds: 1015, 203, 22, 7 + rotate: 90 +boy/eye-front-pupil + bounds: 309, 50, 9, 9 +boy/eye-front-up-eyelid + bounds: 991, 373, 31, 6 +boy/eye-front-up-eyelid-back + bounds: 107, 76, 26, 9 + rotate: 90 +boy/eye-iris-back + bounds: 810, 260, 17, 17 +boy/eye-iris-front + bounds: 902, 230, 18, 18 +boy/eye-white-back + bounds: 599, 179, 20, 12 +boy/eye-white-front + bounds: 544, 183, 27, 13 +boy/eyebrow-back + bounds: 1002, 225, 20, 11 + rotate: 90 +boy/eyebrow-front + bounds: 975, 234, 25, 11 +boy/hair-back + bounds: 629, 289, 122, 81 + rotate: 90 +boy/hair-bangs + bounds: 505, 180, 70, 37 + rotate: 90 +boy/hair-side + bounds: 979, 435, 25, 43 + rotate: 90 +boy/hand-backfingers + bounds: 858, 183, 19, 21 +boy/hand-front-fingers + bounds: 879, 183, 19, 21 +boy/hat + bounds: 218, 121, 93, 56 +boy/leg-front + bounds: 85, 104, 31, 158 +boy/mouth-close + bounds: 467, 100, 21, 5 +girl-blue-cape/mouth-close + bounds: 467, 100, 21, 5 +girl-spring-dress/mouth-close + bounds: 467, 100, 21, 5 +girl/mouth-close + bounds: 467, 100, 21, 5 +boy/mouth-smile + bounds: 1015, 258, 29, 7 + rotate: 90 +boy/nose + bounds: 323, 79, 17, 10 +boy/pompom + bounds: 979, 462, 48, 43 + rotate: 90 +boy/zip + bounds: 922, 231, 14, 23 + rotate: 90 +girl-blue-cape/back-eyebrow + bounds: 527, 106, 18, 12 + rotate: 90 +girl-blue-cape/body-dress + bounds: 2, 264, 109, 246 +girl-blue-cape/body-ribbon + bounds: 576, 193, 50, 38 +girl-blue-cape/cape-back + bounds: 113, 317, 134, 193 +girl-blue-cape/cape-back-up + bounds: 504, 305, 123, 106 +girl-blue-cape/cape-ribbon + bounds: 396, 118, 50, 18 + rotate: 90 +girl-blue-cape/cape-shoulder-back + bounds: 420, 243, 49, 59 +girl-blue-cape/cape-shoulder-front + bounds: 2, 2, 62, 76 +girl-blue-cape/cape-up-front + bounds: 118, 145, 98, 117 +girl-blue-cape/ear + bounds: 837, 181, 19, 23 +girl-spring-dress/ear + bounds: 837, 181, 19, 23 +girl/ear + bounds: 837, 181, 19, 23 +girl-blue-cape/eye-back-low-eyelid + bounds: 810, 252, 17, 6 +girl-spring-dress/eye-back-low-eyelid + bounds: 810, 252, 17, 6 +girl/eye-back-low-eyelid + bounds: 810, 252, 17, 6 +girl-blue-cape/eye-back-pupil + bounds: 309, 40, 8, 9 + rotate: 90 +girl-spring-dress/eye-back-pupil + bounds: 309, 40, 8, 9 + rotate: 90 +girl/eye-back-pupil + bounds: 309, 40, 8, 9 + rotate: 90 +girl-blue-cape/eye-back-up-eyelid + bounds: 573, 179, 24, 12 +girl-spring-dress/eye-back-up-eyelid + bounds: 573, 179, 24, 12 +girl/eye-back-up-eyelid + bounds: 573, 179, 24, 12 +girl-blue-cape/eye-back-up-eyelid-back + bounds: 380, 105, 17, 11 + rotate: 90 +girl-spring-dress/eye-back-up-eyelid-back + bounds: 380, 105, 17, 11 + rotate: 90 +girl/eye-back-up-eyelid-back + bounds: 380, 105, 17, 11 + rotate: 90 +girl-blue-cape/eye-front-low-eyelid + bounds: 1016, 353, 18, 6 + rotate: 90 +girl-spring-dress/eye-front-low-eyelid + bounds: 1016, 353, 18, 6 + rotate: 90 +girl/eye-front-low-eyelid + bounds: 1016, 353, 18, 6 + rotate: 90 +girl-blue-cape/eye-front-pupil + bounds: 363, 94, 9, 9 +girl-spring-dress/eye-front-pupil + bounds: 363, 94, 9, 9 +girl/eye-front-pupil + bounds: 363, 94, 9, 9 +girl-blue-cape/eye-front-up-eyelid + bounds: 679, 413, 30, 14 + rotate: 90 +girl-spring-dress/eye-front-up-eyelid + bounds: 679, 413, 30, 14 + rotate: 90 +girl/eye-front-up-eyelid + bounds: 679, 413, 30, 14 + rotate: 90 +girl-blue-cape/eye-front-up-eyelid-back + bounds: 947, 234, 26, 11 +girl-spring-dress/eye-front-up-eyelid-back + bounds: 947, 234, 26, 11 +girl/eye-front-up-eyelid-back + bounds: 947, 234, 26, 11 +girl-blue-cape/eye-iris-back + bounds: 323, 105, 17, 17 +girl-blue-cape/eye-iris-front + bounds: 467, 107, 18, 18 +girl-blue-cape/eye-white-back + bounds: 621, 175, 20, 16 +girl-spring-dress/eye-white-back + bounds: 621, 175, 20, 16 +girl-blue-cape/eye-white-front + bounds: 643, 175, 20, 16 +girl-spring-dress/eye-white-front + bounds: 643, 175, 20, 16 +girl/eye-white-front + bounds: 643, 175, 20, 16 +girl-blue-cape/front-eyebrow + bounds: 309, 101, 18, 12 + rotate: 90 +girl-blue-cape/hair-back + bounds: 712, 317, 117, 98 +girl-blue-cape/hair-bangs + bounds: 313, 170, 91, 40 + rotate: 90 +girl-blue-cape/hair-head-side-back + bounds: 544, 198, 30, 52 +girl-blue-cape/hair-head-side-front + bounds: 466, 127, 41, 42 +girl-blue-cape/hair-side + bounds: 175, 2, 36, 71 + rotate: 90 +girl-blue-cape/hand-front-fingers + bounds: 902, 207, 19, 21 +girl-spring-dress/hand-front-fingers + bounds: 902, 207, 19, 21 +girl-blue-cape/leg-front + bounds: 519, 413, 30, 158 + rotate: 90 +girl-blue-cape/mouth-smile + bounds: 1015, 227, 29, 7 + rotate: 90 +girl-spring-dress/mouth-smile + bounds: 1015, 227, 29, 7 + rotate: 90 +girl/mouth-smile + bounds: 1015, 227, 29, 7 + rotate: 90 +girl-blue-cape/nose + bounds: 342, 82, 11, 7 +girl-spring-dress/nose + bounds: 342, 82, 11, 7 +girl/nose + bounds: 342, 82, 11, 7 +girl-blue-cape/sleeve-back + bounds: 416, 95, 42, 29 +girl-blue-cape/sleeve-front + bounds: 249, 303, 52, 119 + rotate: 90 +girl-spring-dress/arm-front + bounds: 829, 292, 17, 111 + rotate: 90 +girl-spring-dress/back-eyebrow + bounds: 309, 81, 18, 12 + rotate: 90 +girl-spring-dress/body-up + bounds: 66, 2, 64, 66 +girl-spring-dress/cloak-down + bounds: 758, 227, 50, 50 +girl-spring-dress/cloak-up + bounds: 628, 229, 64, 58 +girl-spring-dress/eye-iris-back + bounds: 342, 105, 17, 17 +girl-spring-dress/eye-iris-front + bounds: 487, 107, 18, 18 +girl-spring-dress/front-eyebrow + bounds: 323, 91, 18, 12 +girl-spring-dress/hair-back + bounds: 370, 417, 147, 93 +girl-spring-dress/hair-bangs + bounds: 829, 250, 91, 40 +girl-spring-dress/hair-head-side-back + bounds: 509, 126, 30, 52 +girl-spring-dress/hair-head-side-front + bounds: 816, 206, 41, 42 +girl-spring-dress/hair-side + bounds: 248, 2, 36, 71 + rotate: 90 +girl-spring-dress/leg-front + bounds: 831, 381, 30, 158 + rotate: 90 +girl-spring-dress/neck + bounds: 85, 70, 20, 32 +girl-spring-dress/shoulder-ribbon + bounds: 175, 44, 36, 24 +girl-spring-dress/skirt + bounds: 2, 80, 182, 81 + rotate: 90 +girl-spring-dress/underskirt + bounds: 519, 445, 175, 65 +girl/arm-front + bounds: 712, 279, 36, 115 + rotate: 90 +girl/back-eyebrow + bounds: 309, 61, 18, 12 + rotate: 90 +girl/bag-base + bounds: 694, 219, 62, 58 +girl/bag-strap-front + bounds: 370, 304, 12, 96 + rotate: 90 +girl/bag-top + bounds: 765, 175, 49, 50 +girl/body + bounds: 370, 318, 97, 132 + rotate: 90 +girl/boot-ribbon-front + bounds: 323, 64, 13, 13 +girl/eye-iris-back + bounds: 361, 105, 17, 17 +girl/eye-iris-front + bounds: 507, 106, 18, 18 +girl/eye-white-back + bounds: 665, 175, 20, 16 +girl/front-eyebrow + bounds: 343, 91, 18, 12 +girl/hair-back + bounds: 696, 417, 147, 93 +girl/hair-bangs + bounds: 922, 247, 91, 40 +girl/hair-flap-down-front + bounds: 415, 171, 70, 65 + rotate: 90 +girl/hair-head-side-back + bounds: 991, 381, 30, 52 +girl/hair-head-side-front + bounds: 859, 206, 41, 42 +girl/hair-patch + bounds: 132, 2, 66, 41 + rotate: 90 +girl/hair-side + bounds: 692, 181, 36, 71 + rotate: 90 +girl/hair-strand-back-1 + bounds: 948, 289, 58, 74 + rotate: 90 +girl/hair-strand-back-2 + bounds: 355, 170, 91, 58 + rotate: 90 +girl/hair-strand-back-3 + bounds: 215, 40, 92, 79 +girl/hair-strand-front-1 + bounds: 234, 263, 38, 94 + rotate: 90 +girl/hair-strand-front-2 + bounds: 576, 233, 70, 50 + rotate: 90 +girl/hair-strand-front-3 + bounds: 313, 124, 44, 81 + rotate: 90 +girl/hand-front-fingers + bounds: 923, 208, 19, 21 +girl/hat + bounds: 218, 179, 93, 82 +girl/leg-front + bounds: 831, 349, 30, 158 + rotate: 90 +girl/pompom + bounds: 416, 126, 48, 43 +girl/scarf + bounds: 113, 264, 119, 51 +girl/scarf-back + bounds: 502, 252, 72, 51 +girl/zip + bounds: 816, 179, 19, 25 diff --git a/spine-ts/spine-canvaskit/example/assets/mix-and-match.png b/spine-ts/spine-canvaskit/example/assets/mix-and-match.png new file mode 100644 index 000000000..634a1e230 Binary files /dev/null and b/spine-ts/spine-canvaskit/example/assets/mix-and-match.png differ diff --git a/spine-ts/spine-canvaskit/example/headless.js b/spine-ts/spine-canvaskit/example/headless.js index 82fd7396f..b3accf8f3 100644 --- a/spine-ts/spine-canvaskit/example/headless.js +++ b/spine-ts/spine-canvaskit/example/headless.js @@ -1,7 +1,7 @@ import * as fs from "fs" import { fileURLToPath } from 'url'; import path from 'path'; -import CanvasKitInit from "canvaskit-wasm/bin/canvaskit.js"; +import CanvasKitInit from "canvaskit-wasm"; import UPNG from "@pdf-lib/upng" import {loadTextureAtlas, SkeletonRenderer, Skeleton, SkeletonBinary, AnimationState, AnimationStateData, AtlasAttachmentLoader, Physics, loadSkeletonData, SkeletonDrawable} from "../dist/index.js" @@ -17,7 +17,6 @@ async function main() { const ck = await CanvasKitInit(); const surface = ck.MakeSurface(600, 400); if (!surface) throw new Error(); - const canvas = surface.getCanvas(); // Load atlas const atlas = await loadTextureAtlas(ck, __dirname + "/assets/spineboy.atlas", async (path) => fs.readFileSync(path)); @@ -47,6 +46,9 @@ async function main() { const imageInfo = { width: 600, height: 400, colorType: ck.ColorType.RGBA_8888, alphaType: ck.AlphaType.Unpremul, colorSpace: ck.ColorSpace.SRGB }; const pixelArray = ck.Malloc(Uint8Array, imageInfo.width * imageInfo.height * 4); for (let time = 0; time <= animationDuration; time += deltaTime) { + // Get the canvas object to render to the surface to + const canvas = surface.getCanvas(); + // Clear the canvas canvas.clear(ck.WHITE); diff --git a/spine-ts/spine-canvaskit/example/ik-following.html b/spine-ts/spine-canvaskit/example/ik-following.html new file mode 100644 index 000000000..b24e8073f --- /dev/null +++ b/spine-ts/spine-canvaskit/example/ik-following.html @@ -0,0 +1,105 @@ + + + + + + + + + + + + + +

IK Following

+

Click/touch to set the aim

+ + + + + + \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/example/index.html b/spine-ts/spine-canvaskit/example/index.html index 5bbb10009..16f03d7f1 100644 --- a/spine-ts/spine-canvaskit/example/index.html +++ b/spine-ts/spine-canvaskit/example/index.html @@ -17,7 +17,7 @@

CanvasKit Example

- + + + + + + +

Micro Benchmark

+
+ + + + + + \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/example/mix-and-match.html b/spine-ts/spine-canvaskit/example/mix-and-match.html new file mode 100644 index 000000000..8bb037e14 --- /dev/null +++ b/spine-ts/spine-canvaskit/example/mix-and-match.html @@ -0,0 +1,84 @@ + + + + + + + + + + + + + +

Skins Mix & Match Example

+ + + + + + \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/example/physics.html b/spine-ts/spine-canvaskit/example/physics.html new file mode 100644 index 000000000..3dac4ec5c --- /dev/null +++ b/spine-ts/spine-canvaskit/example/physics.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + +

IK Following

+

Drag anywhere

+ + + + + + \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/package.json b/spine-ts/spine-canvaskit/package.json index 836e251b1..f1d47ab2e 100644 --- a/spine-ts/spine-canvaskit/package.json +++ b/spine-ts/spine-canvaskit/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-canvaskit", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for CanvasKit for NodeJS", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,7 +31,7 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "4.2.52", + "@esotericsoftware/spine-core": "4.2.61", "canvaskit-wasm": "0.39.1" }, "devDependencies": { diff --git a/spine-ts/spine-canvaskit/src/index.ts b/spine-ts/spine-canvaskit/src/index.ts index f05f77168..12d760be8 100644 --- a/spine-ts/spine-canvaskit/src/index.ts +++ b/spine-ts/spine-canvaskit/src/index.ts @@ -1,99 +1,170 @@ export * from "@esotericsoftware/spine-core"; -import { AnimationState, AnimationStateData, AtlasAttachmentLoader, BlendMode, ClippingAttachment, Color, MeshAttachment, NumberArrayLike, Physics, RegionAttachment, Skeleton, SkeletonBinary, SkeletonClipping, SkeletonData, SkeletonJson, Texture, TextureAtlas, TextureFilter, TextureWrap, Utils } from "@esotericsoftware/spine-core"; -import { Canvas, Surface, CanvasKit, Image, Paint, Shader, BlendMode as CanvasKitBlendMode } from "canvaskit-wasm"; +import { + AnimationState, + AnimationStateData, + AtlasAttachmentLoader, + BlendMode, + ClippingAttachment, + Color, + MeshAttachment, + NumberArrayLike, + Physics, + RegionAttachment, + Skeleton, + SkeletonBinary, + SkeletonClipping, + SkeletonData, + SkeletonJson, + Texture, + TextureAtlas, + TextureFilter, + TextureWrap, + Utils, +} from "@esotericsoftware/spine-core"; +import { + Canvas, + Surface, + CanvasKit, + Image, + Paint, + Shader, + BlendMode as CanvasKitBlendMode, +} from "canvaskit-wasm"; Skeleton.yDown = true; -type CanvasKitImage = { shaders: Shader[], paintPerBlendMode: Map, image: Image }; +type CanvasKitImage = { + shaders: Shader[]; + paintPerBlendMode: Map; + image: Image; +}; // CanvasKit blend modes for premultiplied alpha -function toCkBlendMode(ck: CanvasKit, blendMode: BlendMode) { - switch(blendMode) { - case BlendMode.Normal: return ck.BlendMode.SrcOver; - case BlendMode.Additive: return ck.BlendMode.Plus; - case BlendMode.Multiply: return ck.BlendMode.Modulate; - case BlendMode.Screen: return ck.BlendMode.Screen; - default: return ck.BlendMode.SrcOver; - } +function toCkBlendMode (ck: CanvasKit, blendMode: BlendMode) { + switch (blendMode) { + case BlendMode.Normal: + return ck.BlendMode.SrcOver; + case BlendMode.Additive: + return ck.BlendMode.Plus; + case BlendMode.Multiply: + return ck.BlendMode.SrcOver; + case BlendMode.Screen: + return ck.BlendMode.Screen; + default: + return ck.BlendMode.SrcOver; + } } -function bufferToUtf8String(buffer: any) { - if (typeof Buffer !== 'undefined') { - return buffer.toString('utf-8'); - } else if (typeof TextDecoder !== 'undefined') { - return new TextDecoder('utf-8').decode(buffer); - } else { - throw new Error('Unsupported environment'); - } +function bufferToUtf8String (buffer: any) { + if (typeof Buffer !== "undefined") { + return buffer.toString("utf-8"); + } else if (typeof TextDecoder !== "undefined") { + return new TextDecoder("utf-8").decode(buffer); + } else { + throw new Error("Unsupported environment"); + } } class CanvasKitTexture extends Texture { - getImage(): CanvasKitImage { - return this._image; - } + getImage (): CanvasKitImage { + return this._image; + } - setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void { - } + setFilters (minFilter: TextureFilter, magFilter: TextureFilter): void { } - setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void { - } + setWraps (uWrap: TextureWrap, vWrap: TextureWrap): void { } - dispose(): void { - const data: CanvasKitImage = this._image; - for (const paint of data.paintPerBlendMode.values()) { - paint.delete(); - } - for (const shader of data.shaders) { - shader.delete(); - } - data.image.delete(); - this._image = null; - } + dispose (): void { + const data: CanvasKitImage = this._image; + for (const paint of data.paintPerBlendMode.values()) { + paint.delete(); + } + for (const shader of data.shaders) { + shader.delete(); + } + data.image.delete(); + this._image = null; + } - static async fromFile(ck: CanvasKit, path: string, readFile: (path: string) => Promise): Promise { - const imgData = await readFile(path); - if (!imgData) throw new Error(`Could not load image ${path}`); - const image = ck.MakeImageFromEncoded(imgData); - if (!image) throw new Error(`Could not load image ${path}`); - const paintPerBlendMode = new Map(); - const shaders: Shader[] = []; - for (const blendMode of [BlendMode.Normal, BlendMode.Additive, BlendMode.Multiply, BlendMode.Screen]) { - const paint = new ck.Paint(); - const shader = image.makeShaderOptions(ck.TileMode.Clamp, ck.TileMode.Clamp, ck.FilterMode.Linear, ck.MipmapMode.Linear); - paint.setShader(shader); - paint.setBlendMode(toCkBlendMode(ck, blendMode)); - paintPerBlendMode.set(blendMode, paint); - shaders.push(shader); - } - return new CanvasKitTexture({ shaders, paintPerBlendMode, image }); - } + static async fromFile ( + ck: CanvasKit, + path: string, + readFile: (path: string) => Promise + ): Promise { + const imgData = await readFile(path); + if (!imgData) throw new Error(`Could not load image ${path}`); + const image = ck.MakeImageFromEncoded(imgData); + if (!image) throw new Error(`Could not load image ${path}`); + const paintPerBlendMode = new Map(); + const shaders: Shader[] = []; + for (const blendMode of [ + BlendMode.Normal, + BlendMode.Additive, + BlendMode.Multiply, + BlendMode.Screen, + ]) { + const paint = new ck.Paint(); + const shader = image.makeShaderOptions( + ck.TileMode.Clamp, + ck.TileMode.Clamp, + ck.FilterMode.Linear, + ck.MipmapMode.Linear + ); + paint.setShader(shader); + paint.setBlendMode(toCkBlendMode(ck, blendMode)); + paintPerBlendMode.set(blendMode, paint); + shaders.push(shader); + } + return new CanvasKitTexture({ shaders, paintPerBlendMode, image }); + } } /** * Loads a {@link TextureAtlas} and its atlas page images from the given file path using the `readFile(path: string): Promise` function. * Throws an `Error` if the file or one of the atlas page images could not be loaded. */ -export async function loadTextureAtlas(ck: CanvasKit, atlasFile: string, readFile: (path: string) => Promise): Promise { - const atlas = new TextureAtlas(bufferToUtf8String(await readFile(atlasFile))); - const slashIndex = atlasFile.lastIndexOf("/"); - const parentDir = slashIndex >= 0 ? atlasFile.substring(0, slashIndex + 1) + "/" : ""; - for (const page of atlas.pages) { - const texture = await CanvasKitTexture.fromFile(ck, parentDir + page.name, readFile); - page.setTexture(texture); - } - return atlas; +export async function loadTextureAtlas ( + ck: CanvasKit, + atlasFile: string, + readFile: (path: string) => Promise +): Promise { + const atlas = new TextureAtlas(bufferToUtf8String(await readFile(atlasFile))); + const slashIndex = atlasFile.lastIndexOf("/"); + const parentDir = + slashIndex >= 0 ? atlasFile.substring(0, slashIndex + 1) + "/" : ""; + for (const page of atlas.pages) { + const texture = await CanvasKitTexture.fromFile( + ck, + parentDir + page.name, + readFile + ); + page.setTexture(texture); + } + return atlas; } /** * Loads a {@link SkeletonData} from the given file path (`.json` or `.skel`) using the `readFile(path: string): Promise` function. * Attachments will be looked up in the provided atlas. */ -export async function loadSkeletonData(skeletonFile: string, atlas: TextureAtlas, readFile: (path: string) => Promise): Promise { - const attachmentLoader = new AtlasAttachmentLoader(atlas); - const loader = skeletonFile.endsWith(".json") ? new SkeletonJson(attachmentLoader) : new SkeletonBinary(attachmentLoader); - const skeletonData = loader.readSkeletonData(await readFile(skeletonFile)); - return skeletonData; +export async function loadSkeletonData ( + skeletonFile: string, + atlas: TextureAtlas, + readFile: (path: string) => Promise, + scale = 1 +): Promise { + const attachmentLoader = new AtlasAttachmentLoader(atlas); + const loader = skeletonFile.endsWith(".json") + ? new SkeletonJson(attachmentLoader) + : new SkeletonBinary(attachmentLoader); + loader.scale = scale; + let data = await readFile(skeletonFile); + if (skeletonFile.endsWith(".json")) { + data = bufferToUtf8String(data); + } + const skeletonData = loader.readSkeletonData(data); + return skeletonData; } /** @@ -101,57 +172,60 @@ export async function loadSkeletonData(skeletonFile: string, atlas: TextureAtlas * be shared by any number of drawables. */ export class SkeletonDrawable { - public readonly skeleton: Skeleton; - public readonly animationState: AnimationState; + public readonly skeleton: Skeleton; + public readonly animationState: AnimationState; - /** - * Constructs a new drawble from the skeleton data. - */ - constructor(skeletonData: SkeletonData) { - this.skeleton = new Skeleton(skeletonData); - this.animationState = new AnimationState(new AnimationStateData(skeletonData)); - } + /** + * Constructs a new drawble from the skeleton data. + */ + constructor (skeletonData: SkeletonData) { + this.skeleton = new Skeleton(skeletonData); + this.animationState = new AnimationState( + new AnimationStateData(skeletonData) + ); + } - /** - * Updates the animation state and skeleton time by the delta time. Applies the - * animations to the skeleton and calculates the final pose of the skeleton. - * - * @param deltaTime the time since the last update in seconds - * @param physicsUpdate optional {@link Physics} update mode. - */ - update(deltaTime: number, physicsUpdate: Physics = Physics.update) { - this.animationState.update(deltaTime); - this.skeleton.update(deltaTime); - this.animationState.apply(this.skeleton); - this.skeleton.updateWorldTransform(physicsUpdate); - } + /** + * Updates the animation state and skeleton time by the delta time. Applies the + * animations to the skeleton and calculates the final pose of the skeleton. + * + * @param deltaTime the time since the last update in seconds + * @param physicsUpdate optional {@link Physics} update mode. + */ + update (deltaTime: number, physicsUpdate: Physics = Physics.update) { + this.animationState.update(deltaTime); + this.skeleton.update(deltaTime); + this.animationState.apply(this.skeleton); + this.skeleton.updateWorldTransform(physicsUpdate); + } } /** * Renders a {@link Skeleton} or {@link SkeletonDrawable} to a CanvasKit {@link Canvas}. */ export class SkeletonRenderer { - private clipper = new SkeletonClipping(); - private tempColor = new Color(); - private tempColor2 = new Color(); - private static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; - private scratchPositions = Utils.newFloatArray(100); - private scratchColors = Utils.newFloatArray(100); + private clipper = new SkeletonClipping(); + private tempColor = new Color(); + private tempColor2 = new Color(); + private static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; + private scratchPositions = Utils.newFloatArray(100); + private scratchColors = Utils.newFloatArray(100); + private scratchUVs = Utils.newFloatArray(100); - /** - * Creates a new skeleton renderer. - * @param ck the {@link CanvasKit} instance returned by `CanvasKitInit()`. - */ - constructor(private ck: CanvasKit) {} + /** + * Creates a new skeleton renderer. + * @param ck the {@link CanvasKit} instance returned by `CanvasKitInit()`. + */ + constructor (private ck: CanvasKit) { } - /** - * Renders a skeleton or skeleton drawable in its current pose to the canvas. - * @param canvas the canvas to render to. - * @param skeleton the skeleton or drawable to render. - */ - render(canvas: Canvas, skeleton: Skeleton | SkeletonDrawable) { - if (skeleton instanceof SkeletonDrawable) skeleton = skeleton.skeleton; - let clipper = this.clipper; + /** + * Renders a skeleton or skeleton drawable in its current pose to the canvas. + * @param canvas the canvas to render to. + * @param skeleton the skeleton or drawable to render. + */ + render (canvas: Canvas, skeleton: Skeleton | SkeletonDrawable) { + if (skeleton instanceof SkeletonDrawable) skeleton = skeleton.skeleton; + let clipper = this.clipper; let drawOrder = skeleton.drawOrder; let skeletonColor = skeleton.color; @@ -160,20 +234,20 @@ export class SkeletonRenderer { if (!slot.bone.active) { clipper.clipEndWithSlot(slot); continue; - } + } let attachment = slot.getAttachment(); - let positions = this.scratchPositions; - let colors = this.scratchColors; - let uvs: NumberArrayLike; + let positions = this.scratchPositions; + let colors = this.scratchColors; + let uvs: NumberArrayLike; let texture: CanvasKitTexture; - let triangles: Array; - let attachmentColor: Color; - let numVertices = 0; + let triangles: Array; + let attachmentColor: Color; + let numVertices = 0; if (attachment instanceof RegionAttachment) { let region = attachment as RegionAttachment; - positions = positions.length < 8 ? Utils.newFloatArray(8) : positions; - numVertices = 4; + positions = positions.length < 8 ? Utils.newFloatArray(8) : positions; + numVertices = 4; region.computeWorldVertices(slot, positions, 0, 2); triangles = SkeletonRenderer.QUAD_TRIANGLES; uvs = region.uvs as Float32Array; @@ -181,9 +255,19 @@ export class SkeletonRenderer { attachmentColor = region.color; } else if (attachment instanceof MeshAttachment) { let mesh = attachment as MeshAttachment; - positions = positions.length < mesh.worldVerticesLength ? Utils.newFloatArray(mesh.worldVerticesLength) : positions; - numVertices = mesh.worldVerticesLength >> 1; - mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, positions, 0, 2); + positions = + positions.length < mesh.worldVerticesLength + ? Utils.newFloatArray(mesh.worldVerticesLength) + : positions; + numVertices = mesh.worldVerticesLength >> 1; + mesh.computeWorldVertices( + slot, + 0, + mesh.worldVerticesLength, + positions, + 0, + 2 + ); triangles = mesh.triangles; texture = mesh.region?.texture as CanvasKitTexture; uvs = mesh.uvs as Float32Array; @@ -199,42 +283,63 @@ export class SkeletonRenderer { if (texture) { if (clipper.isClipping()) { - clipper.clipTrianglesUnpacked(positions, triangles, triangles.length, uvs); - positions = clipper.clippedVertices; - uvs = clipper.clippedUVs; - triangles = clipper.clippedTriangles; + clipper.clipTrianglesUnpacked( + positions, + triangles, + triangles.length, + uvs + ); + positions = clipper.clippedVertices; + uvs = clipper.clippedUVs; + triangles = clipper.clippedTriangles; } - let slotColor = slot.color; + let slotColor = slot.color; let finalColor = this.tempColor; finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r; finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g; finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b; finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a; - if (colors.length / 4 < numVertices) colors = Utils.newFloatArray(numVertices * 4); - for (let i = 0, n = numVertices * 4; i < n; i += 4) { - colors[i] = finalColor.r; - colors[i + 1] = finalColor.g; - colors[i + 2] = finalColor.b; - colors[i + 3] = finalColor.a; - } + if (colors.length / 4 < numVertices) + colors = Utils.newFloatArray(numVertices * 4); + for (let i = 0, n = numVertices * 4; i < n; i += 4) { + colors[i] = finalColor.r; + colors[i + 1] = finalColor.g; + colors[i + 2] = finalColor.b; + colors[i + 3] = finalColor.a; + } - const scaledUvs = new Array(uvs.length); - const width = texture.getImage().image.width(); - const height = texture.getImage().image.height(); - for (let i = 0; i < uvs.length; i+=2) { - scaledUvs[i] = uvs[i] * width; - scaledUvs[i + 1] = uvs[i + 1] * height; - } + const scaledUvs = + this.scratchUVs.length < uvs.length + ? Utils.newFloatArray(uvs.length) + : this.scratchUVs; + const width = texture.getImage().image.width(); + const height = texture.getImage().image.height(); + for (let i = 0; i < uvs.length; i += 2) { + scaledUvs[i] = uvs[i] * width; + scaledUvs[i + 1] = uvs[i + 1] * height; + } - const blendMode = slot.data.blendMode; - const vertices = this.ck.MakeVertices(this.ck.VertexMode.Triangles, positions, scaledUvs, colors, triangles, false); - canvas.drawVertices(vertices, this.ck.BlendMode.Modulate, texture.getImage().paintPerBlendMode.get(blendMode)!); + const blendMode = slot.data.blendMode; + const vertices = this.ck.MakeVertices( + this.ck.VertexMode.Triangles, + positions, + scaledUvs, + colors, + triangles, + false + ); + canvas.drawVertices( + vertices, + this.ck.BlendMode.Modulate, + texture.getImage().paintPerBlendMode.get(blendMode)! + ); + vertices.delete(); } clipper.clipEndWithSlot(slot); } clipper.clipEnd(); - } -} \ No newline at end of file + } +} diff --git a/spine-ts/spine-core/package.json b/spine-ts/spine-core/package.json index 46cb1a04a..2ef2b6d06 100644 --- a/spine-ts/spine-core/package.json +++ b/spine-ts/spine-core/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-core", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for the web.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/spine-ts/spine-core/src/Animation.ts b/spine-ts/spine-core/src/Animation.ts index ff9a5d0b8..c54085ca6 100644 --- a/spine-ts/spine-core/src/Animation.ts +++ b/spine-ts/spine-core/src/Animation.ts @@ -835,6 +835,11 @@ export class InheritTimeline extends Timeline implements BoneTimeline { let bone = skeleton.bones[this.boneIndex]; if (!bone.active) return; + if (direction == MixDirection.mixOut) { + if (blend == MixBlend.setup) bone.inherit = bone.data.inherit; + return; + } + let frames = this.frames; if (time < frames[0]) { if (blend == MixBlend.setup || blend == MixBlend.first) bone.inherit = bone.data.inherit; diff --git a/spine-ts/spine-core/src/Bone.ts b/spine-ts/spine-core/src/Bone.ts index f2b7272be..fc082520d 100644 --- a/spine-ts/spine-core/src/Bone.ts +++ b/spine-ts/spine-core/src/Bone.ts @@ -200,12 +200,13 @@ export class Bone implements Updatable { break; } case Inherit.NoRotationOrReflection: { + let sx = 1 / this.skeleton.scaleX, sy = 1 / this.skeleton.scaleY; + pa *= sx; + pc *= sy; let s = pa * pa + pc * pc; let prx = 0; if (s > 0.0001) { - s = Math.abs(pa * pd - pb * pc) / s; - pa /= this.skeleton.scaleX; - pc /= this.skeleton.scaleY; + s = Math.abs(pa * pd * sy - pb * sx * pc) / s; pb = pc * s; pd = pa * s; prx = Math.atan2(pc, pa) * MathUtils.radDeg; @@ -311,10 +312,8 @@ export class Bone implements Updatable { switch (this.inherit) { case Inherit.NoRotationOrReflection: { let s = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); - let sa = pa / this.skeleton.scaleX; - let sc = pc / this.skeleton.scaleY; - pb = -sc * s * this.skeleton.scaleX; - pd = sa * s * this.skeleton.scaleY; + pb = -pc * this.skeleton.scaleX * s / this.skeleton.scaleY; + pd = pa * this.skeleton.scaleY * s / this.skeleton.scaleX; pid = 1 / (pa * pd - pb * pc); ia = pd * pid; ib = pb * pid; diff --git a/spine-ts/spine-core/src/IkConstraint.ts b/spine-ts/spine-core/src/IkConstraint.ts index 268af28a6..c4694c5d1 100644 --- a/spine-ts/spine-core/src/IkConstraint.ts +++ b/spine-ts/spine-core/src/IkConstraint.ts @@ -270,8 +270,9 @@ export class IkConstraint implements Updatable { q = -(c1 + q) * 0.5; let r0 = q / c2, r1 = c / q; let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; - if (r * r <= dd) { - y = Math.sqrt(dd - r * r) * bendDir; + r0 = dd - r * r; + if (r0 >= 0) { + y = Math.sqrt(r0) * bendDir; a1 = ta - Math.atan2(y, r); a2 = Math.atan2(y / psy, (r - l1) / psx); break outer; diff --git a/spine-ts/spine-core/src/PhysicsConstraint.ts b/spine-ts/spine-core/src/PhysicsConstraint.ts index d90493e53..2870ecbf7 100644 --- a/spine-ts/spine-core/src/PhysicsConstraint.ts +++ b/spine-ts/spine-core/src/PhysicsConstraint.ts @@ -136,9 +136,10 @@ export class PhysicsConstraint implements Updatable { this.reset(); // Fall through. case Physics.update: + const skeleton = this.skeleton; const delta = Math.max(this.skeleton.time - this.lastTime, 0); this.remaining += delta; - this.lastTime = this.skeleton.time; + this.lastTime = skeleton.time; const bx = bone.worldX, by = bone.worldY; if (this._reset) { @@ -146,16 +147,18 @@ export class PhysicsConstraint implements Updatable { this.ux = bx; this.uy = by; } else { - let a = this.remaining, i = this.inertia, q = this.data.limit * delta, t = this.data.step, f = this.skeleton.data.referenceScale, d = -1; + let a = this.remaining, i = this.inertia, t = this.data.step, f = this.skeleton.data.referenceScale, d = -1; + let qx = this.data.limit * delta, qy = qx * Math.abs(skeleton.scaleY); + qx *= Math.abs(skeleton.scaleX); if (x || y) { if (x) { const u = (this.ux - bx) * i; - this.xOffset += u > q ? q : u < -q ? -q : u; + this.xOffset += u > qx ? qx : u < -qx ? -qx : u; this.ux = bx; } if (y) { const u = (this.uy - by) * i; - this.yOffset += u > q ? q : u < -q ? -q : u; + this.yOffset += u > qy ? qy : u < -qy ? -qy : u; this.uy = by; } if (a >= t) { @@ -181,14 +184,14 @@ export class PhysicsConstraint implements Updatable { if (rotateOrShearX || scaleX) { let ca = Math.atan2(bone.c, bone.a), c = 0, s = 0, mr = 0; let dx = this.cx - bone.worldX, dy = this.cy - bone.worldY; - if (dx > q) - dx = q; - else if (dx < -q) // - dx = -q; - if (dy > q) - dy = q; - else if (dy < -q) // - dy = -q; + if (dx > qx) + dx = qx; + else if (dx < -qx) // + dx = -qx; + if (dy > qy) + dy = qy; + else if (dy < -qy) // + dy = -qy; if (rotateOrShearX) { mr = (this.data.rotate + this.data.shearX) * mix; let r = Math.atan2(dy + this.ty, dx + this.tx) - ca - this.rotateOffset * mr; diff --git a/spine-ts/spine-core/src/SkeletonBinary.ts b/spine-ts/spine-core/src/SkeletonBinary.ts index 7e6621a84..518d1ec51 100644 --- a/spine-ts/spine-core/src/SkeletonBinary.ts +++ b/spine-ts/spine-core/src/SkeletonBinary.ts @@ -64,7 +64,7 @@ export class SkeletonBinary { this.attachmentLoader = attachmentLoader; } - readSkeletonData (binary: Uint8Array | ArrayBuffer): SkeletonData { + readSkeletonData (binary: Uint8Array | ArrayBuffer): SkeletonData { let scale = this.scale; let skeletonData = new SkeletonData(); diff --git a/spine-ts/spine-core/src/SkeletonClipping.ts b/spine-ts/spine-core/src/SkeletonClipping.ts index 9f5cae242..e31dbd929 100644 --- a/spine-ts/spine-core/src/SkeletonClipping.ts +++ b/spine-ts/spine-core/src/SkeletonClipping.ts @@ -81,17 +81,58 @@ export class SkeletonClipping { return this.clipAttachment != null; } + /** + * @deprecated Use clipTriangles without verticesLength parameter. Mark for removal in 4.3. + */ + clipTriangles (vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number): void; + + /** + * @deprecated Use clipTriangles without verticesLength parameter. Mark for removal in 4.3. + */ + clipTriangles (vertices: NumberArrayLike, verticesLength: number, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean): void; + clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number): void; - clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, - light: Color, dark: Color, twoColor: boolean): void; - clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs?: NumberArrayLike, - light?: Color, dark?: Color, twoColor?: boolean): void { + clipTriangles (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number, uvs: NumberArrayLike, light: Color, dark: Color, twoColor: boolean): void; + clipTriangles ( + vertices: NumberArrayLike, + verticesLengthOrTriangles: number | NumberArrayLike, + trianglesOrTrianglesLength: NumberArrayLike | number, + trianglesLengthOrUvs?: number | NumberArrayLike, + uvsOrLight?: NumberArrayLike | Color, + lightOrDark?: Color, + darkOrTwoColor?: Color | boolean, + twoColorParam?: boolean + ): void { + // Determine which overload is being used + let triangles: NumberArrayLike; + let trianglesLength: number; + let uvs: NumberArrayLike | undefined; + let light: Color | undefined; + let dark: Color | undefined; + let twoColor: boolean | undefined; + + if (typeof verticesLengthOrTriangles === 'number') { + triangles = trianglesOrTrianglesLength as NumberArrayLike; + trianglesLength = trianglesLengthOrUvs as number; + uvs = uvsOrLight as NumberArrayLike; + light = lightOrDark as Color | undefined; + dark = darkOrTwoColor as Color | undefined; + twoColor = twoColorParam; + } else { + triangles = verticesLengthOrTriangles; + trianglesLength = trianglesOrTrianglesLength as number; + uvs = trianglesLengthOrUvs as NumberArrayLike; + light = uvsOrLight as Color | undefined; + dark = lightOrDark as Color | undefined; + twoColor = darkOrTwoColor as boolean; + } if (uvs && light && dark && typeof twoColor === 'boolean') this.clipTrianglesRender(vertices, triangles, trianglesLength, uvs, light, dark, twoColor); else this.clipTrianglesNoRender(vertices, triangles, trianglesLength); } + private clipTrianglesNoRender (vertices: NumberArrayLike, triangles: NumberArrayLike, trianglesLength: number) { let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; diff --git a/spine-ts/spine-phaser/package.json b/spine-ts/spine-phaser/package.json index a5e5bb0ee..b124328a9 100644 --- a/spine-ts/spine-phaser/package.json +++ b/spine-ts/spine-phaser/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-phaser", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for the Phaser.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,8 +31,11 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "4.2.52", - "@esotericsoftware/spine-webgl": "4.2.52", - "@esotericsoftware/spine-canvas": "4.2.52" + "@esotericsoftware/spine-core": "4.2.61", + "@esotericsoftware/spine-webgl": "4.2.61", + "@esotericsoftware/spine-canvas": "4.2.61" + }, + "peerDependencies": { + "phaser": "^3.60.0" } } \ No newline at end of file diff --git a/spine-ts/spine-phaser/src/SpinePlugin.ts b/spine-ts/spine-phaser/src/SpinePlugin.ts index 5ff853c90..c0aa93e97 100644 --- a/spine-ts/spine-phaser/src/SpinePlugin.ts +++ b/spine-ts/spine-phaser/src/SpinePlugin.ts @@ -27,7 +27,7 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Phaser from "phaser"; +import * as Phaser from "phaser"; import { SPINE_ATLAS_CACHE_KEY, SPINE_GAME_OBJECT_TYPE, SPINE_SKELETON_DATA_FILE_TYPE, SPINE_ATLAS_FILE_TYPE, SPINE_SKELETON_FILE_CACHE_KEY as SPINE_SKELETON_DATA_CACHE_KEY } from "./keys.js"; import { AtlasAttachmentLoader, GLTexture, SceneRenderer, Skeleton, SkeletonBinary, SkeletonData, SkeletonJson, TextureAtlas } from "@esotericsoftware/spine-webgl" import { SpineGameObject, SpineGameObjectBoundsProvider } from "./SpineGameObject.js"; diff --git a/spine-ts/spine-pixi/package.json b/spine-ts/spine-pixi/package.json index fcd165fdb..2b307a3b1 100644 --- a/spine-ts/spine-pixi/package.json +++ b/spine-ts/spine-pixi/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-pixi", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for the web.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,7 +31,7 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "4.2.52" + "@esotericsoftware/spine-core": "4.2.61" }, "peerDependencies": { "@pixi/core": "^7.2.4", diff --git a/spine-ts/spine-pixi/src/Spine.ts b/spine-ts/spine-pixi/src/Spine.ts index 2b4702203..3c8b38017 100644 --- a/spine-ts/spine-pixi/src/Spine.ts +++ b/spine-ts/spine-pixi/src/Spine.ts @@ -143,6 +143,7 @@ export class Spine extends Container { private lightColor = new Color(); private darkColor = new Color(); + private clippingVertAux = new Float32Array(6); constructor (skeletonData: SkeletonData, options?: ISpineOptions) { super(); @@ -225,10 +226,19 @@ export class Spine extends Container { } /** + * Check the existence of a mesh for the given slot. + * If you want to manually handle which meshes go on which slot and how you cache, overwrite this method. + */ + protected hasMeshForSlot (slot: Slot) { + return this.meshesCache.has(slot); + } + + /** + * Search the mesh corresponding to the given slot or create it, if it does not exists. * If you want to manually handle which meshes go on which slot and how you cache, overwrite this method. */ protected getMeshForSlot (slot: Slot): ISlotMesh { - if (!this.meshesCache.has(slot)) { + if (!this.hasMeshForSlot(slot)) { let mesh = this.slotMeshFactory(); this.addChild(mesh); this.meshesCache.set(slot, mesh); @@ -319,7 +329,9 @@ export class Spine extends Container { } } private updatePixiObject (pixiObject: Container, slot: Slot, zIndex: number) { - pixiObject.setTransform(slot.bone.worldX, slot.bone.worldY, slot.bone.getWorldScaleX(), slot.bone.getWorldScaleX(), slot.bone.getWorldRotationX() * MathUtils.degRad); + pixiObject.position.set(slot.bone.worldX, slot.bone.worldY); + pixiObject.scale.set(slot.bone.getWorldScaleX(), slot.bone.getWorldScaleX()); + pixiObject.rotation = slot.bone.getWorldRotationX() * MathUtils.degRad; pixiObject.zIndex = zIndex + 1; pixiObject.alpha = this.skeleton.color.a * slot.color.a; } @@ -334,9 +346,15 @@ export class Spine extends Container { if (!pixiMaskSource.computed) { pixiMaskSource.computed = true; const clippingAttachment = pixiMaskSource.slot.attachment as ClippingAttachment; - const world = Array.from(clippingAttachment.vertices); - clippingAttachment.computeWorldVertices(pixiMaskSource.slot, 0, clippingAttachment.worldVerticesLength, world, 0, 2); - mask.clear().lineStyle(0).beginFill(0x000000).drawPolygon(world); + const worldVerticesLength = clippingAttachment.worldVerticesLength; + if (this.clippingVertAux.length < worldVerticesLength) this.clippingVertAux = new Float32Array(worldVerticesLength); + clippingAttachment.computeWorldVertices(pixiMaskSource.slot, 0, worldVerticesLength, this.clippingVertAux, 0, 2); + mask.clear().lineStyle(0).beginFill(0x000000); + mask.moveTo(this.clippingVertAux[0], this.clippingVertAux[1]); + for (let i = 2; i < worldVerticesLength; i += 2) { + mask.lineTo(this.clippingVertAux[i], this.clippingVertAux[i + 1]); + } + mask.finishPoly(); } pixiObject.mask = mask; } else if (pixiObject.mask) { @@ -344,13 +362,13 @@ export class Spine extends Container { } } - /* + /* * Colors in pixi are premultiplied. * Pixi blending modes are modified to work with premultiplied colors. We cannot create custom blending modes. * Textures are loaded as premultiplied (see assers/atlasLoader.ts: alphaMode: `page.pma ? ALPHA_MODES.PMA : ALPHA_MODES.UNPACK`): * - textures non premultiplied are premultiplied on GPU on upload * - textures premultiplied are uploaded on GPU as is since they are already premultiplied - * + * * We need to take this into consideration and calculates final colors for both light and dark color as if textures were always premultiplied. * This implies for example that alpha for dark tint is always 1. This is way in DarkTintRenderer we have only the alpha of the light color. * If we ever want to load texture as non premultiplied on GPU, we must add a new dark alpha parameter to the TintMaterial and set the alpha. @@ -410,6 +428,9 @@ export class Spine extends Container { pixiMaskSource = { slot, computed: false }; continue; } else { + if (this.hasMeshForSlot(slot)) { + this.getMeshForSlot(slot).visible = false; + } Spine.clipper.clipEndWithSlot(slot); this.pixiMaskCleanup(slot); continue; @@ -481,6 +502,7 @@ export class Spine extends Container { } const mesh = this.getMeshForSlot(slot); + mesh.renderable = true; mesh.zIndex = zIndex; mesh.updateFromSpineData(texture, slot.data.blendMode, slot.data.name, finalVertices, finalVerticesLength, finalIndices, finalIndicesLength, useDarkColor); } diff --git a/spine-ts/spine-pixi/src/assets/atlasLoader.ts b/spine-ts/spine-pixi/src/assets/atlasLoader.ts index 22c1ecb96..9892892a4 100644 --- a/spine-ts/spine-pixi/src/assets/atlasLoader.ts +++ b/spine-ts/spine-pixi/src/assets/atlasLoader.ts @@ -28,7 +28,7 @@ *****************************************************************************/ import { TextureAtlas } from "@esotericsoftware/spine-core"; import { SpineTexture } from "../SpineTexture.js"; -import type { AssetExtension, Loader } from "@pixi/assets"; +import type { AssetExtension, Loader, UnresolvedAsset } from "@pixi/assets"; import { Assets } from "@pixi/assets"; import { LoaderParserPriority, checkExtension } from "@pixi/assets"; import type { Texture } from "@pixi/core"; @@ -39,6 +39,18 @@ type RawAtlas = string; const spineTextureAtlasLoader: AssetExtension = { extension: ExtensionType.Asset, + resolver: { + test: (value: string): boolean => checkExtension(value, ".atlas"), + parse: (value: string): UnresolvedAsset => { + const split = value.split('.'); + return { + resolution: parseFloat(settings.RETINA_PREFIX?.exec(value)?.[1] ?? '1'), + format: split[split.length - 2], + src: value, + }; + }, + }, + loader: { extension: { type: ExtensionType.LoadParser, diff --git a/spine-ts/spine-player/package.json b/spine-ts/spine-player/package.json index 5b3db6257..a0079423f 100644 --- a/spine-ts/spine-player/package.json +++ b/spine-ts/spine-player/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-player", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for the web.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,6 +31,6 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-webgl": "4.2.52" + "@esotericsoftware/spine-webgl": "4.2.61" } } \ No newline at end of file diff --git a/spine-ts/spine-threejs/package.json b/spine-ts/spine-threejs/package.json index 68d2f079c..387a4fbd5 100644 --- a/spine-ts/spine-threejs/package.json +++ b/spine-ts/spine-threejs/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-threejs", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for the web.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,6 +31,6 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "4.2.52" + "@esotericsoftware/spine-core": "4.2.61" } } \ No newline at end of file diff --git a/spine-ts/spine-webgl/package.json b/spine-ts/spine-webgl/package.json index ac20a2f46..1585467d1 100644 --- a/spine-ts/spine-webgl/package.json +++ b/spine-ts/spine-webgl/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-webgl", - "version": "4.2.52", + "version": "4.2.61", "description": "The official Spine Runtimes for the web.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,6 +31,6 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "4.2.52" + "@esotericsoftware/spine-core": "4.2.61" } } \ No newline at end of file diff --git a/spine-ue/Content/GettingStarted/01-basic-animation.umap b/spine-ue/Content/GettingStarted/01-basic-animation.umap index 44c329f58..570296ae1 100644 Binary files a/spine-ue/Content/GettingStarted/01-basic-animation.umap and b/spine-ue/Content/GettingStarted/01-basic-animation.umap differ diff --git a/spine-ue/Content/GettingStarted/06-cpp.umap b/spine-ue/Content/GettingStarted/06-cpp.umap index 16ccfaa52..1a4d9c873 100644 Binary files a/spine-ue/Content/GettingStarted/06-cpp.umap and b/spine-ue/Content/GettingStarted/06-cpp.umap differ diff --git a/spine-ue/Content/GettingStarted/Blueprints/UmgRaptor.uasset b/spine-ue/Content/GettingStarted/Blueprints/UmgRaptor.uasset index 965c458fa..7c7a7256b 100644 Binary files a/spine-ue/Content/GettingStarted/Blueprints/UmgRaptor.uasset and b/spine-ue/Content/GettingStarted/Blueprints/UmgRaptor.uasset differ diff --git a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp index f8bd0f901..6a617addd 100644 --- a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp +++ b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineAtlasAsset.cpp @@ -95,14 +95,14 @@ void USpineAtlasAsset::BeginDestroy() { class UETextureLoader : public TextureLoader { void load(AtlasPage &page, const String &path) { - page.texture = (void*)(uintptr_t)page.index; + page.texture = (void *) (uintptr_t) page.index; } void unload(void *texture) { } }; -UETextureLoader textureLoader; +UETextureLoader _spineUETextureLoader; Atlas *USpineAtlasAsset::GetAtlas() { if (!atlas) { @@ -113,7 +113,7 @@ Atlas *USpineAtlasAsset::GetAtlas() { std::string t = TCHAR_TO_UTF8(*rawData); atlas = new (__FILE__, __LINE__) - Atlas(t.c_str(), strlen(t.c_str()), "", &textureLoader); + Atlas(t.c_str(), strlen(t.c_str()), "", &_spineUETextureLoader); } return this->atlas; } diff --git a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp index 58aabe0d9..a48e786d3 100644 --- a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp +++ b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonComponent.cpp @@ -287,6 +287,30 @@ float USpineSkeletonComponent::GetAnimationDuration(FString AnimationName) { return 0; } +void USpineSkeletonComponent::PhysicsTranslate(float x, float y) { + CheckState(); + if (skeleton) { + skeleton->physicsTranslate(x, y); + } +} + +void USpineSkeletonComponent::PhysicsRotate(float x, float y, float degrees) { + CheckState(); + if (skeleton) { + skeleton->physicsRotate(x, y, degrees); + } +} + +void USpineSkeletonComponent::ResetPhysicsConstraints() { + CheckState(); + if (skeleton) { + Vector &constraints = skeleton->getPhysicsConstraints(); + for (int i = 0, n = (int) constraints.size(); i < n; i++) { + constraints[i]->reset(); + } + } +} + void USpineSkeletonComponent::BeginPlay() { Super::BeginPlay(); } diff --git a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp index 6ac48ea76..b317eaf35 100644 --- a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp +++ b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineSkeletonRendererComponent.cpp @@ -268,7 +268,7 @@ void USpineSkeletonRendererComponent::UpdateMesh(USpineSkeletonComponent *compon // to the correct skeleton data yet, we won't find any regions. // ignore regions for which we can't find a material UMaterialInstanceDynamic *material = nullptr; - int foundPageIndex = (int)(intptr_t)attachmentAtlasRegion->rendererObject; + int foundPageIndex = (int) (intptr_t) attachmentAtlasRegion->rendererObject; if (foundPageIndex == -1) { clipper.clipEnd(*slot); continue; diff --git a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp index 6a45169dc..a6034adf4 100644 --- a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp +++ b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Private/SpineWidget.cpp @@ -368,6 +368,16 @@ bool USpineWidget::HasSlot(const FString SlotName) { return false; } +void USpineWidget::SetSlotColor(const FString SlotName, const FColor SlotColor) { + CheckState(); + if (skeleton) { + spine::Slot *slot = skeleton->findSlot(TCHAR_TO_UTF8(*SlotName)); + if (slot) { + slot->getColor().set(SlotColor.R / 255.f, SlotColor.G / 255.f, SlotColor.B / 255.f, SlotColor.A / 255.f); + } + } +} + void USpineWidget::GetAnimations(TArray &Animations) { CheckState(); if (skeleton) { @@ -514,3 +524,27 @@ void USpineWidget::ClearTrack(int trackIndex) { state->clearTrack(trackIndex); } } + +void USpineWidget::PhysicsTranslate(float x, float y) { + CheckState(); + if (skeleton) { + skeleton->physicsTranslate(x, y); + } +} + +void USpineWidget::PhysicsRotate(float x, float y, float degrees) { + CheckState(); + if (skeleton) { + skeleton->physicsRotate(x, y, degrees); + } +} + +void USpineWidget::ResetPhysicsConstraints() { + CheckState(); + if (skeleton) { + Vector &constraints = skeleton->getPhysicsConstraints(); + for (int i = 0, n = (int) constraints.size(); i < n; i++) { + constraints[i]->reset(); + } + } +} \ No newline at end of file diff --git a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h index c040110ce..94dcf9eef 100644 --- a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h +++ b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineSkeletonComponent.h @@ -127,6 +127,15 @@ public: UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") float GetAnimationDuration(FString AnimationName); + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void PhysicsTranslate(float x, float y); + + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void PhysicsRotate(float x, float y, float degrees); + + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void ResetPhysicsConstraints(); + UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton") FSpineBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform; diff --git a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h index 2836a484a..0019a6eea 100644 --- a/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h +++ b/spine-ue/Plugins/SpinePlugin/Source/SpinePlugin/Public/SpineWidget.h @@ -141,6 +141,9 @@ public: UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") bool HasSlot(const FString SlotName); + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void SetSlotColor(const FString SlotName, const FColor SlotColor); + UFUNCTION(BlueprintPure, Category = "Components|Spine|Skeleton") void GetAnimations(TArray &Animations); @@ -150,6 +153,15 @@ public: UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") float GetAnimationDuration(FString AnimationName); + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void PhysicsTranslate(float x, float y); + + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void PhysicsRotate(float x, float y, float degrees); + + UFUNCTION(BlueprintCallable, Category = "Components|Spine|Skeleton") + void ResetPhysicsConstraints(); + UPROPERTY(BlueprintAssignable, Category = "Components|Spine|Skeleton") FSpineWidgetBeforeUpdateWorldTransformDelegate BeforeUpdateWorldTransform; diff --git a/spine-unity/Assets/Spine Examples/Other Examples/RenderTexture FadeOut Transparency.unity b/spine-unity/Assets/Spine Examples/Other Examples/RenderTexture FadeOut Transparency.unity index 596dd690e..57ff07b00 100644 --- a/spine-unity/Assets/Spine Examples/Other Examples/RenderTexture FadeOut Transparency.unity +++ b/spine-unity/Assets/Spine Examples/Other Examples/RenderTexture FadeOut Transparency.unity @@ -1059,7 +1059,7 @@ MonoBehaviour: quadMaterial: {fileID: 2100000, guid: 4c507f887c6274a44a603d96e0eabf2a, type: 2} renderTexture: {fileID: 0} targetCamera: {fileID: 0} - shaderPasses: ffffffff + shaderPasses: 00000000 --- !u!114 &1786065615 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1357,7 +1357,7 @@ MonoBehaviour: quadMaterial: {fileID: 2100000, guid: afeb0ae2ea2cda94796515bf8d1b3cb1, type: 2} renderTexture: {fileID: 0} targetCamera: {fileID: 0} - shaderPasses: ffffffff + shaderPasses: 00000000 customRenderRect: {fileID: 1089682727} meshRendererMaterialForTexture: - texture: {fileID: 2800000, guid: 4ea2c33e839afb34c98f66e892b3b2d2, type: 3} diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs index bafe6ee4a..a04063b9f 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTexture.cs @@ -128,6 +128,8 @@ namespace Spine.Unity.Examples { } void RenderOntoQuad (SkeletonRenderer skeletonRenderer) { + if (meshFilter == null) + meshFilter = this.GetComponent(); Vector3 size = meshFilter.sharedMesh.bounds.size; if (size.x == 0f || size.y == 0f) { AssignNullMeshAtQuad(); diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs index 6c4c9de86..d3d4c6d14 100644 --- a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/SkeletonRenderTexture/SkeletonRenderTextureBase.cs @@ -48,8 +48,8 @@ namespace Spine.Unity.Examples { public Camera targetCamera; [Tooltip("Shader passes to render to the RenderTexture. E.g. set the first element " + "to -1 to render all shader passes, or set it to 0 to only render the first " + - "shader pass, which may be required when using URP.")] - public int[] shaderPasses = new int[1] { -1 }; + "shader pass, which may be required when using URP or shadow-casting shaders.")] + public int[] shaderPasses = new int[1] { 0 }; protected CommandBuffer commandBuffer; protected Vector2Int screenSize; diff --git a/spine-unity/Assets/Spine Examples/package.json b/spine-unity/Assets/Spine Examples/package.json index 705bb9ab6..9f15b3a28 100644 --- a/spine-unity/Assets/Spine Examples/package.json +++ b/spine-unity/Assets/Spine Examples/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.spine-unity-examples", "displayName": "spine-unity Runtime Examples", "description": "This plugin provides example scenes and scripts for the spine-unity runtime.", - "version": "4.2.35", + "version": "4.2.37", "unity": "2018.3", "author": { "name": "Esoteric Software", diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs index a9f583af0..98afec85a 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/AssetUtility.cs @@ -61,6 +61,7 @@ using System.Linq; using System.Reflection; using System.Text; using UnityEditor; +using UnityEditor.VersionControl; using UnityEngine; using CompatibilityProblemInfo = Spine.Unity.SkeletonDataCompatibility.CompatibilityProblemInfo; @@ -218,7 +219,7 @@ namespace Spine.Unity.Editor { } else { // On a "Reimport All" the order of imports can be wrong, thus LoadAssetAtPath() above could return null. // as a workaround, we provide a fallback reader. - input = File.Open(skeletonDataPath, FileMode.Open, FileAccess.Read); + input = File.Open(skeletonDataPath, System.IO.FileMode.Open, FileAccess.Read); } binary.ReadSkeletonData(input); } finally { @@ -493,6 +494,8 @@ namespace Spine.Unity.Editor { } } } + + RevertUnchangedOnPerforce(atlasPaths, skeletonPaths, newAtlases); } static void AddDependentAtlasIfImageChanged (List atlasPaths, List imagePaths) { @@ -526,6 +529,32 @@ namespace Spine.Unity.Editor { } } + /// Prevents automatic check-out of unchanged, identically re-created assets (e.g. when re-imported) + /// when using Perforce VCS. + static void RevertUnchangedOnPerforce (List atlasPaths, List skeletonPaths, List newAtlases) { + Plugin versionControl = Provider.GetActivePlugin(); + if (versionControl != null && versionControl.name == "Perforce") { + AssetList assets = new AssetList(); + + foreach (string atlasPath in atlasPaths) { + assets.Add(Provider.GetAssetByPath(atlasPath)); + } + foreach (PathAndProblemInfo skeletonPathInfo in skeletonPaths) { + if (skeletonPathInfo.compatibilityProblems == null) + assets.Add(Provider.GetAssetByPath(skeletonPathInfo.path)); + } + foreach (AtlasAssetBase atlas in newAtlases) { + if (atlas != null) + assets.Add(Provider.GetAssetByPath(AssetDatabase.GetAssetPath(atlas))); + foreach (Material atlasMaterial in atlas.Materials) { + if (atlasMaterial != null) + assets.Add(Provider.GetAssetByPath(AssetDatabase.GetAssetPath(atlasMaterial))); + } + } + Provider.Revert(assets, RevertMode.Unchanged); + } + } + static void ReloadSkeletonData (string skeletonJSONPath, CompatibilityProblemInfo compatibilityProblemInfo) { string dir = Path.GetDirectoryName(skeletonJSONPath).Replace('\\', '/'); TextAsset textAsset = AssetDatabase.LoadAssetAtPath(skeletonJSONPath); diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/BlendModeMaterialsUtility.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/BlendModeMaterialsUtility.cs index 8f920da52..09f080004 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/BlendModeMaterialsUtility.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/BlendModeMaterialsUtility.cs @@ -207,6 +207,18 @@ namespace Spine.Unity.Editor { if (File.Exists(blendMaterialPath)) { newReplacement.material = AssetDatabase.LoadAssetAtPath(blendMaterialPath); } else { + if (materialTemplate == null) { + Debug.LogError(string.Format("Failed to create blend mode material: Material template for " + + "blend mode '{0}' was null. Re-importing might fix this issue.", + materialSuffix), originalMaterial); + return null; + } + if (originalMaterial == null) { + Debug.LogError(string.Format("Failed to create blend mode material for atlas page '{0}': Original material for " + + "blend mode '{1}' was null. Re-importing might fix this issue.", + originalPage.name, materialSuffix)); + return null; + } Material blendModeMaterial = new Material(materialTemplate) { name = originalMaterial.name + " " + materialTemplate.name, mainTexture = originalMaterial.mainTexture diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs index 3e1f3aab3..6f2f5020e 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineEditorUtilities.cs @@ -128,10 +128,10 @@ namespace Spine.Unity.Editor { Mesh mesh = meshFilter.sharedMesh; if (mesh == null) continue; - string meshName = string.Format("Skeleton Prefab Mesh \"{0}\"", renderer.name); + string meshName = string.Format("Skeleton Prefab Mesh [{0}]", renderer.name); if (nameUsageCount.ContainsKey(meshName)) { nameUsageCount[meshName]++; - meshName = string.Format("Skeleton Prefab Mesh \"{0} ({1})\"", renderer.name, nameUsageCount[meshName]); + meshName = string.Format("Skeleton Prefab Mesh [{0} ({1})]", renderer.name, nameUsageCount[meshName]); } else { nameUsageCount.Add(meshName, 0); } diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs index c1e4dcf3f..f2360e2fa 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Utility/SpineInspectorUtility.cs @@ -149,10 +149,20 @@ namespace Spine.Unity.Editor { } } } - newPropertyPath = propertyPath.Remove(propertyPath.Length - localPathLength, localPathLength) + propertyName; relativeProperty = property.serializedObject.FindProperty(newPropertyPath); } + // If this fails as well, try at any base property up the hierarchy + if (relativeProperty == null) { + int dotIndex = propertyPath.Length - property.name.Length - 1; + while (relativeProperty == null) { + dotIndex = propertyPath.LastIndexOf('.', dotIndex - 1); + if (dotIndex < 0) + break; + newPropertyPath = propertyPath.Remove(dotIndex + 1) + propertyName; + relativeProperty = property.serializedObject.FindProperty(newPropertyPath); + } + } } return relativeProperty; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs index 4dbc7d2f1..4e031166e 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonMecanimRootMotion.cs @@ -88,8 +88,8 @@ namespace Spine.Unity { mecanimLayerFlags = DefaultMecanimLayerFlags; } - protected override void Start () { - base.Start(); + public override void Initialize () { + base.Initialize(); skeletonMecanim = GetComponent(); if (skeletonMecanim) { skeletonMecanim.Translator.OnClipApplied -= OnClipApplied; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs index 6bc6c0b60..2086c3e2a 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotion.cs @@ -88,8 +88,8 @@ namespace Spine.Unity { animationTrackFlags = DefaultAnimationTrackFlags; } - protected override void Start () { - base.Start(); + public override void Initialize () { + base.Initialize(); IAnimationStateComponent animstateComponent = skeletonComponent as IAnimationStateComponent; this.animationState = (animstateComponent != null) ? animstateComponent.AnimationState : null; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs index a85b077ba..ddcdf1361 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/RootMotion/SkeletonRootMotionBase.cs @@ -27,6 +27,12 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +// In order to respect TransformConstraints modifying the scale of parent bones, +// GetScaleAffectingRootMotion() now uses parentBone.AScaleX and AScaleY instead +// of previously used ScaleX and ScaleY. If you require the previous behaviour, +// comment out the define below. +#define USE_APPLIED_PARENT_SCALE + using Spine.Unity.AnimationTools; using System; using System.Collections.Generic; @@ -42,8 +48,7 @@ namespace Spine.Unity { #region Inspector [SpineBone] - [SerializeField] - protected string rootMotionBoneName = "root"; + public string rootMotionBoneName = "root"; public bool transformPositionX = true; public bool transformPositionY = true; public bool transformRotation = false; @@ -155,6 +160,14 @@ namespace Spine.Unity { } protected virtual void Start () { + Initialize(); + } + + protected void InitializeOnRebuild (ISkeletonAnimation animatedSkeletonComponent) { + Initialize(); + } + + public virtual void Initialize () { skeletonComponent = GetComponent(); GatherTopLevelBones(); SetRootMotionBone(rootMotionBoneName); @@ -167,6 +180,16 @@ namespace Spine.Unity { if (skeletonAnimation != null) { skeletonAnimation.UpdateLocal -= HandleUpdateLocal; skeletonAnimation.UpdateLocal += HandleUpdateLocal; + + skeletonAnimation.OnAnimationRebuild -= InitializeOnRebuild; + skeletonAnimation.OnAnimationRebuild += InitializeOnRebuild; + + SkeletonUtility skeletonUtility = GetComponent(); + if (skeletonUtility != null) { + // SkeletonUtilityBone shall receive UpdateLocal callbacks for bone-following after root motion + // clears the root-bone position. + skeletonUtility.ResubscribeEvents(); + } } } @@ -198,6 +221,13 @@ namespace Spine.Unity { } Vector2 rigidbodyDisplacement2D = new Vector2(rigidbodyDisplacement.x, rigidbodyDisplacement.y); + // Note: MovePosition seems to be the only precise and reliable way to set movement delta, + // for both 2D and 3D rigidbodies. + // Setting velocity like "rigidBody2D.velocity = movement/deltaTime" works perfectly in mid-air + // without gravity and ground collision, unfortunately when on the ground, friction causes severe + // slowdown. Using a zero-friction PhysicsMaterial leads to sliding endlessly along the ground as + // soon as forces are applied. Additionally, there is no rigidBody2D.isGrounded, requiring our own + // checks. rigidBody2D.MovePosition(gravityAndVelocityMovement + new Vector2(rigidBody2D.position.x, rigidBody2D.position.y) + rigidbodyDisplacement2D + additionalRigidbody2DMovement); rigidBody2D.MoveRotation(rigidbody2DRotation + rigidBody2D.rotation); @@ -271,7 +301,8 @@ namespace Spine.Unity { this.rootMotionBone = bone; FindTransformConstraintsAffectingBone(); } else { - Debug.Log("Bone named \"" + name + "\" could not be found."); + Debug.Log("Bone named \"" + name + "\" could not be found. " + + "Set 'skeletonRootMotion.rootMotionBoneName' before calling 'skeletonAnimation.Initialize(true)'."); this.rootMotionBoneIndex = 0; this.rootMotionBone = skeleton.RootBone; } @@ -623,8 +654,13 @@ namespace Spine.Unity { parentBoneScale = Vector2.one; Bone scaleBone = rootMotionBone; while ((scaleBone = scaleBone.Parent) != null) { +#if USE_APPLIED_PARENT_SCALE + parentBoneScale.x *= scaleBone.AScaleX; + parentBoneScale.y *= scaleBone.AScaleY; +#else parentBoneScale.x *= scaleBone.ScaleX; parentBoneScale.y *= scaleBone.ScaleY; +#endif } totalScale = Vector2.Scale(totalScale, parentBoneScale); totalScale *= AdditionalScale; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs index 82b49e147..9c88ff382 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonGraphic.cs @@ -93,6 +93,7 @@ namespace Spine.Unity { /// Offset relative to the pivot position, before potential layout scale is applied. [SerializeField] protected Vector2 pivotOffset = Vector2.zero; [SerializeField] protected float referenceScale = 1f; + [SerializeField] protected float layoutScale = 1f; #if UNITY_EDITOR protected LayoutMode previousLayoutScaleMode = LayoutMode.None; [SerializeField] protected Vector2 rectTransformSize = Vector2.zero; @@ -742,8 +743,9 @@ namespace Spine.Unity { SetRectTransformSize(submeshGraphic, size); submeshGraphic.rectTransform.pivot = p; } - this.referenceSize = size; + referenceScale = referenceScale * layoutScale; + layoutScale = 1f; } public static void SetRectTransformSize (Graphic target, Vector2 size) { @@ -943,7 +945,7 @@ namespace Spine.Unity { meshScale = (canvas == null) ? 100 : canvas.referencePixelsPerUnit; if (layoutScaleMode != LayoutMode.None) { meshScale *= referenceScale; - float layoutScale = GetLayoutScale(layoutScaleMode); + layoutScale = GetLayoutScale(layoutScaleMode); if (!EditReferenceRect) { meshScale *= layoutScale; } @@ -1043,7 +1045,7 @@ namespace Spine.Unity { meshScale = (canvas == null) ? 100 : canvas.referencePixelsPerUnit; if (layoutScaleMode != LayoutMode.None) { meshScale *= referenceScale; - float layoutScale = GetLayoutScale(layoutScaleMode); + layoutScale = GetLayoutScale(layoutScaleMode); if (!EditReferenceRect) { meshScale *= layoutScale; } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs index aa68a59a1..2efe049d4 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonMecanim.cs @@ -210,7 +210,7 @@ namespace Spine.Unity { public event OnClipAppliedDelegate OnClipApplied { add { _OnClipApplied += value; } remove { _OnClipApplied -= value; } } - public enum MixMode { AlwaysMix, MixNext, Hard } + public enum MixMode { AlwaysMix, MixNext, Hard, Match } readonly Dictionary animationTable = new Dictionary(IntEqualityComparer.Instance); readonly Dictionary clipNameHashCodeTable = new Dictionary(AnimationClipEqualityComparer.Instance); @@ -226,6 +226,9 @@ namespace Spine.Unity { public readonly List clipInfos = new List(); public readonly List nextClipInfos = new List(); public readonly List interruptingClipInfos = new List(); + public float[] clipResolvedWeights = new float[0]; + public float[] nextClipResolvedWeights = new float[0]; + public float[] interruptingClipResolvedWeights = new float[0]; public AnimatorStateInfo stateInfo; public AnimatorStateInfo nextStateInfo; @@ -273,7 +276,8 @@ namespace Spine.Unity { } private bool ApplyAnimation (Skeleton skeleton, AnimatorClipInfo info, AnimatorStateInfo stateInfo, - int layerIndex, float layerWeight, MixBlend layerBlendMode, bool useClipWeight1 = false) { + int layerIndex, float layerWeight, MixBlend layerBlendMode, + bool useCustomClipWeight = false, float customClipWeight = 1.0f) { float weight = info.weight * layerWeight; if (weight < WeightEpsilon) return false; @@ -283,7 +287,7 @@ namespace Spine.Unity { return false; float time = AnimationTime(stateInfo.normalizedTime, info.clip.length, info.clip.isLooping, stateInfo.speed < 0); - weight = useClipWeight1 ? layerWeight : weight; + weight = useCustomClipWeight ? layerWeight * customClipWeight : weight; clip.Apply(skeleton, 0, time, info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In); if (_OnClipApplied != null) @@ -294,7 +298,7 @@ namespace Spine.Unity { private bool ApplyInterruptionAnimation (Skeleton skeleton, bool interpolateWeightTo1, AnimatorClipInfo info, AnimatorStateInfo stateInfo, int layerIndex, float layerWeight, MixBlend layerBlendMode, float interruptingClipTimeAddition, - bool useClipWeight1 = false) { + bool useCustomClipWeight = false, float customClipWeight = 1.0f) { float clipWeight = interpolateWeightTo1 ? (info.weight + 1.0f) * 0.5f : info.weight; float weight = clipWeight * layerWeight; @@ -307,7 +311,7 @@ namespace Spine.Unity { float time = AnimationTime(stateInfo.normalizedTime + interruptingClipTimeAddition, info.clip.length, info.clip.isLooping, stateInfo.speed < 0); - weight = useClipWeight1 ? layerWeight : weight; + weight = useCustomClipWeight ? layerWeight * customClipWeight : weight; clip.Apply(skeleton, 0, time, info.clip.isLooping, null, weight, layerBlendMode, MixDirection.In); if (_OnClipApplied != null) { @@ -442,11 +446,39 @@ namespace Spine.Unity { layer, layerWeight, layerBlendMode, interruptingClipTimeAddition); } } + } else if (mode == MixMode.Match) { + // Calculate matching Spine lerp(lerp(A, B, w2), C, w3) weights + // from Unity's absolute weights A*W1 + B*W2 + C*W3. + MatchWeights(layerClipInfos[layer], hasNext, isInterruptionActive, clipInfoCount, nextClipInfoCount, interruptingClipInfoCount, + clipInfo, nextClipInfo, interruptingClipInfo); + + float[] customWeights = layerClipInfos[layer].clipResolvedWeights; + for (int c = 0; c < clipInfoCount; c++) { + ApplyAnimation(skeleton, clipInfo[c], stateInfo, layer, layerWeight, layerBlendMode, + true, customWeights[c]); + } + if (hasNext) { + customWeights = layerClipInfos[layer].nextClipResolvedWeights; + for (int c = 0; c < nextClipInfoCount; c++) { + ApplyAnimation(skeleton, nextClipInfo[c], nextStateInfo, layer, layerWeight, layerBlendMode, + true, customWeights[c]); + } + } + if (isInterruptionActive) { + customWeights = layerClipInfos[layer].interruptingClipResolvedWeights; + for (int c = 0; c < interruptingClipInfoCount; c++) { + ApplyInterruptionAnimation(skeleton, interpolateWeightTo1, + interruptingClipInfo[c], interruptingStateInfo, + layer, layerWeight, layerBlendMode, interruptingClipTimeAddition, + true, customWeights[c]); + } + } } else { // case MixNext || Hard // Apply first non-zero weighted clip int c = 0; for (; c < clipInfoCount; c++) { - if (!ApplyAnimation(skeleton, clipInfo[c], stateInfo, layer, layerWeight, layerBlendMode, useClipWeight1: true)) + if (!ApplyAnimation(skeleton, clipInfo[c], stateInfo, layer, layerWeight, layerBlendMode, + true, 1.0f)) continue; ++c; break; } @@ -460,7 +492,8 @@ namespace Spine.Unity { // Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights) if (mode == MixMode.Hard) { for (; c < nextClipInfoCount; c++) { - if (!ApplyAnimation(skeleton, nextClipInfo[c], nextStateInfo, layer, layerWeight, layerBlendMode, useClipWeight1: true)) + if (!ApplyAnimation(skeleton, nextClipInfo[c], nextStateInfo, layer, layerWeight, layerBlendMode, + true, 1.0f)) continue; ++c; break; } @@ -479,7 +512,7 @@ namespace Spine.Unity { for (; c < interruptingClipInfoCount; c++) { if (ApplyInterruptionAnimation(skeleton, interpolateWeightTo1, interruptingClipInfo[c], interruptingStateInfo, - layer, layerWeight, layerBlendMode, interruptingClipTimeAddition, useClipWeight1: true)) { + layer, layerWeight, layerBlendMode, interruptingClipTimeAddition, true, 1.0f)) { ++c; break; } @@ -496,6 +529,46 @@ namespace Spine.Unity { } } + /// + /// Resolve matching weights from Unity's absolute weights A*w1 + B*w2 + C*w3 to + /// Spine's lerp(lerp(A, B, x), C, y) weights, in reverse order of clips. + /// + protected void MatchWeights (ClipInfos clipInfos, bool hasNext, bool isInterruptionActive, + int clipInfoCount, int nextClipInfoCount, int interruptingClipInfoCount, + IList clipInfo, IList nextClipInfo, IList interruptingClipInfo) { + + if (clipInfos.clipResolvedWeights.Length < clipInfoCount) { + System.Array.Resize(ref clipInfos.clipResolvedWeights, clipInfoCount); + } + if (hasNext && clipInfos.nextClipResolvedWeights.Length < nextClipInfoCount) { + System.Array.Resize(ref clipInfos.nextClipResolvedWeights, nextClipInfoCount); + } + if (isInterruptionActive && clipInfos.interruptingClipResolvedWeights.Length < interruptingClipInfoCount) { + System.Array.Resize(ref clipInfos.interruptingClipResolvedWeights, interruptingClipInfoCount); + } + + float inverseWeight = 1.0f; + if (isInterruptionActive) { + for (int c = interruptingClipInfoCount - 1; c >= 0; c--) { + float unityWeight = interruptingClipInfo[c].weight; + clipInfos.interruptingClipResolvedWeights[c] = interruptingClipInfo[c].weight * inverseWeight; + inverseWeight /= (1.0f - unityWeight); + } + } + if (hasNext) { + for (int c = nextClipInfoCount - 1; c >= 0; c--) { + float unityWeight = nextClipInfo[c].weight; + clipInfos.nextClipResolvedWeights[c] = nextClipInfo[c].weight * inverseWeight; + inverseWeight /= (1.0f - unityWeight); + } + } + for (int c = clipInfoCount - 1; c >= 0; c--) { + float unityWeight = clipInfo[c].weight; + clipInfos.clipResolvedWeights[c] = (c == 0) ? 1f : clipInfo[c].weight * inverseWeight; + inverseWeight /= (1.0f - unityWeight); + } + } + public KeyValuePair GetActiveAnimationAndTime (int layer) { if (layer >= layerClipInfos.Length) return new KeyValuePair(null, 0); diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs index c41645618..8f9ade241 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonRenderer.cs @@ -303,7 +303,7 @@ namespace Spine.Unity { [SerializeField] protected Transform physicsMovementRelativeTo = null; /// Used for applying Transform translation to skeleton PhysicsConstraints. - protected Vector2 lastPosition; + protected Vector3 lastPosition; /// Used for applying Transform rotation to skeleton PhysicsConstraints. protected float lastRotation; @@ -520,8 +520,8 @@ namespace Spine.Unity { public virtual void ApplyTransformMovementToPhysics () { if (Application.isPlaying) { if (physicsPositionInheritanceFactor != Vector2.zero) { - Vector2 position = GetPhysicsTransformPosition(); - Vector2 positionDelta = position - lastPosition; + Vector3 position = GetPhysicsTransformPosition(); + Vector3 positionDelta = position - lastPosition; positionDelta = transform.InverseTransformVector(positionDelta); if (physicsMovementRelativeTo != null) { @@ -541,7 +541,7 @@ namespace Spine.Unity { } } - protected Vector2 GetPhysicsTransformPosition () { + protected Vector3 GetPhysicsTransformPosition () { if (physicsMovementRelativeTo == null) { return transform.position; } else { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs index 749a81eae..958ed60d2 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Components/SkeletonUtility/SkeletonUtility.cs @@ -238,8 +238,37 @@ namespace Spine.Unity { bool needToReprocessBones; public void ResubscribeEvents () { - OnDisable(); - OnEnable(); + ResubscribeIndependentEvents(); + ResubscribeDependentEvents(); + } + + void ResubscribeIndependentEvents () { + if (skeletonRenderer != null) { + skeletonRenderer.OnRebuild -= HandleRendererReset; + skeletonRenderer.OnRebuild += HandleRendererReset; + } else if (skeletonGraphic != null) { + skeletonGraphic.OnRebuild -= HandleRendererReset; + skeletonGraphic.OnRebuild += HandleRendererReset; + skeletonGraphic.OnPostProcessVertices -= UpdateToMeshScaleAndOffset; + skeletonGraphic.OnPostProcessVertices += UpdateToMeshScaleAndOffset; + } + + if (skeletonAnimation != null) { + skeletonAnimation.UpdateLocal -= UpdateLocal; + skeletonAnimation.UpdateLocal += UpdateLocal; + } + } + + void ResubscribeDependentEvents () { + if (skeletonAnimation != null) { + skeletonAnimation.UpdateWorld -= UpdateWorld; + skeletonAnimation.UpdateComplete -= UpdateComplete; + + if (hasOverrideBones || hasConstraints) + skeletonAnimation.UpdateWorld += UpdateWorld; + if (hasConstraints) + skeletonAnimation.UpdateComplete += UpdateComplete; + } } void OnEnable () { @@ -259,23 +288,8 @@ namespace Spine.Unity { skeletonGraphic != null ? skeletonGraphic.GetComponent() : GetComponent(); } - - if (skeletonRenderer != null) { - skeletonRenderer.OnRebuild -= HandleRendererReset; - skeletonRenderer.OnRebuild += HandleRendererReset; - } else if (skeletonGraphic != null) { - skeletonGraphic.OnRebuild -= HandleRendererReset; - skeletonGraphic.OnRebuild += HandleRendererReset; - skeletonGraphic.OnPostProcessVertices -= UpdateToMeshScaleAndOffset; - skeletonGraphic.OnPostProcessVertices += UpdateToMeshScaleAndOffset; - } - - if (skeletonAnimation != null) { - skeletonAnimation.UpdateLocal -= UpdateLocal; - skeletonAnimation.UpdateLocal += UpdateLocal; - } - CollectBones(); + ResubscribeEvents(); } void Start () { @@ -360,23 +374,12 @@ namespace Spine.Unity { } hasConstraints |= constraintComponents.Count > 0; - - if (skeletonAnimation != null) { - skeletonAnimation.UpdateWorld -= UpdateWorld; - skeletonAnimation.UpdateComplete -= UpdateComplete; - - if (hasOverrideBones || hasConstraints) - skeletonAnimation.UpdateWorld += UpdateWorld; - - if (hasConstraints) - skeletonAnimation.UpdateComplete += UpdateComplete; - } - needToReprocessBones = false; } else { boneComponents.Clear(); constraintComponents.Clear(); } + ResubscribeDependentEvents(); } void UpdateLocal (ISkeletonAnimation anim) { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs index 36303dde8..269a777c0 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshGenerator.cs @@ -37,8 +37,9 @@ #define MANUALLY_INLINE_VECTOR_OPERATORS #endif -// Not for optimization. Do not disable. -#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +// Optimization option: Allows faster BuildMeshWithArrays call and avoids calling SetTriangles at the cost of +// checking for mesh differences (vertex counts, member-wise attachment list compare) every frame. +#define SPINE_TRIANGLECHECK //#define SPINE_DEBUG // New optimization option to avoid rendering fully transparent attachments at slot alpha 0. @@ -285,7 +286,12 @@ namespace Spine.Unity { instructionOutput.rawVertexCount = totalRawVertexCount; #endif - if (totalRawVertexCount > 0) { +#if SPINE_TRIANGLECHECK + bool hasAnyVertices = totalRawVertexCount > 0; +#else + bool hasAnyVertices = true; +#endif + if (hasAnyVertices) { workingSubmeshInstructions.Resize(1); workingSubmeshInstructions.Items[0] = current; } else { @@ -364,10 +370,12 @@ namespace Spine.Unity { Slot slot = drawOrderItems[i]; if (!slot.Bone.Active #if SLOT_ALPHA_DISABLES_ATTACHMENT - || slot.A == 0f + || (slot.A == 0f && slot.Data != clippingEndSlot) #endif ) { +#if SPINE_TRIANGLECHECK workingAttachmentsItems[i] = null; +#endif continue; } if (slot.Data.BlendMode == BlendMode.Additive) current.hasPMAAdditiveSlot = true; @@ -458,7 +466,11 @@ namespace Spine.Unity { Material material = (region is Material) ? (Material)region : (Material)((AtlasRegion)region).page.rendererObject; #endif +#if !SPINE_TRIANGLECHECK + if (current.forceSeparate || !System.Object.ReferenceEquals(current.material, material)) { // Material changed. Add the previous submesh. +#else if (current.forceSeparate || (current.rawVertexCount > 0 && !System.Object.ReferenceEquals(current.material, material))) { // Material changed. Add the previous submesh. +#endif { // Add current.endSlot = i; current.preActiveClippingSlotSource = lastPreActiveClipping; @@ -799,6 +811,9 @@ namespace Spine.Unity { // Use this faster method when no clipping is involved. public void BuildMeshWithArrays (SkeletonRendererInstruction instruction, bool updateTriangles) { +#if !SPINE_TRIANGLECHECK + return; +#else Settings settings = this.settings; bool canvasGroupTintBlack = settings.tintBlack && settings.canvasGroupCompatible; int totalVertexCount = instruction.rawVertexCount; @@ -1113,6 +1128,7 @@ namespace Spine.Unity { } } } +#endif // SPINE_TRIANGLECHECK } public void ScaleVertexData (float scale) { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs index 2b037a7c1..22b749065 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/MeshRendererBuffers.cs @@ -27,8 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -// Not for optimization. Do not disable. -#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +// Optimization option: Allows faster BuildMeshWithArrays call and avoids calling SetTriangles at the cost of +// checking for mesh differences (vertex counts, member-wise attachment list compare) every frame. +#define SPINE_TRIANGLECHECK //#define SPINE_DEBUG using System; diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs index 4b1c192d0..4a564bd05 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SkeletonRendererInstruction.cs @@ -27,8 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -// Not for optimization. Do not disable. -#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +// Optimization option: Allows faster BuildMeshWithArrays call and avoids calling SetTriangles at the cost of +// checking for mesh differences (vertex counts, member-wise attachment list compare) every frame. +#define SPINE_TRIANGLECHECK //#define SPINE_DEBUG // Important Note: When disabling this define, also disable the one in MeshGenerator.cs @@ -49,6 +50,11 @@ namespace Spine.Unity { public bool hasActiveClipping; public int rawVertexCount = -1; public readonly ExposedList attachments = new ExposedList(); +#else + /// Returns constant true to avoid BuildMeshWithArrays in renderers. + public bool hasActiveClipping { get { return true; } } + /// Returns constant vertex count for early-return if-clauses in renderers. + public int rawVertexCount { get { return 1; } } #endif public void Clear () { @@ -60,9 +66,11 @@ namespace Spine.Unity { this.submeshInstructions.Clear(false); } +#if SPINE_TRIANGLECHECK public void Dispose () { attachments.Clear(true); } +#endif public void SetWithSubset (ExposedList instructions, int startSubmesh, int endSubmesh) { #if SPINE_TRIANGLECHECK diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs index 0b36a289f..e15e457d6 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Mesh Generation/SpineMesh.cs @@ -27,8 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -// Not for optimization. Do not disable. -#define SPINE_TRIANGLECHECK // Avoid calling SetTriangles at the cost of checking for mesh differences (vertex counts, memberwise attachment list compare) every frame. +// Optimization option: Allows faster BuildMeshWithArrays call and avoids calling SetTriangles at the cost of +// checking for mesh differences (vertex counts, member-wise attachment list compare) every frame. +#define SPINE_TRIANGLECHECK //#define SPINE_DEBUG using System; @@ -66,6 +67,9 @@ namespace Spine.Unity { public int rawVertexCount; public int rawFirstVertexIndex; public bool hasClipping; +#else + /// Returns constant vertex count for early-return if clauses in renderers. + public int rawVertexCount { get { return 1; } } #endif public bool hasPMAAdditiveSlot; diff --git a/spine-unity/Assets/Spine/package.json b/spine-unity/Assets/Spine/package.json index 36b034007..babde3265 100644 --- a/spine-unity/Assets/Spine/package.json +++ b/spine-unity/Assets/Spine/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.spine-unity", "displayName": "spine-unity Runtime", "description": "This plugin provides the spine-unity runtime core.", - "version": "4.2.75", + "version": "4.2.88", "unity": "2018.3", "author": { "name": "Esoteric Software", @@ -10,6 +10,10 @@ "url": "http://esotericsoftware.com/" }, "dependencies": { + "com.unity.ugui" : "1.0.0", + "com.unity.modules.animation" : "1.0.0", + "com.unity.modules.physics" : "1.0.0", + "com.unity.modules.physics2d" : "1.0.0", "com.esotericsoftware.spine.spine-csharp": "4.2.0" }, "repository": { diff --git a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Documentation/README.md b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Documentation/README.md index c09d3074f..e47c6f18d 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Documentation/README.md +++ b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Documentation/README.md @@ -7,3 +7,7 @@ The plugin adds a `SpineVisualElement` control element to be used with UI Toolki For usage of the `SpineVisualElement` control element, you can check out the included `UI Toolkit Example.unity` example scene and `SpineUIToolkit.uxml` file which can be installed via the `Samples` tab in the Unity Package Manager window. The new `SpineVisualElement` can be found in the Unity `UI Builder` window under `Library - Project - Custom Controls` `Spine - Unity - SpineVisualElement`. It can be added to your hierarchy and configured as normal UI Toolkit elements while providing Spine skeleton attributes as well. + +### Limitations + +Premultiply-alpha (PMA) atlas textures are not supported due to limitations of the UI Toolkit `VisualElement` API, not allowing custom shaders. Please export your atlas textures as straight alpha to avoid artifacts. diff --git a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor.meta b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor.meta new file mode 100644 index 000000000..6c2c3ce8a --- /dev/null +++ b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 020c4dfc4cd28f8409ea82818e31d040 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor/SpineVisualElementAttributeDrawers.cs b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor/SpineVisualElementAttributeDrawers.cs new file mode 100644 index 000000000..b8c1681c5 --- /dev/null +++ b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor/SpineVisualElementAttributeDrawers.cs @@ -0,0 +1,119 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2024, 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. + *****************************************************************************/ + +//#define CHANGE_BOUNDS_ON_ANIMATION_CHANGE + +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Spine.Unity.Editor { + + [CustomPropertyDrawer(typeof(BoundsFromAnimationAttribute))] + public class BoundsFromAnimationAttributeDrawer : PropertyDrawer { + + protected BoundsFromAnimationAttribute TargetAttribute { get { return (BoundsFromAnimationAttribute)attribute; } } + + public override VisualElement CreatePropertyGUI (SerializedProperty boundsProperty) { + var container = new VisualElement(); + PropertyField referenceMeshBounds = new PropertyField(); + referenceMeshBounds.BindProperty(boundsProperty); + + var parentPropertyPath = boundsProperty.propertyPath.Substring(0, boundsProperty.propertyPath.LastIndexOf('.')); + var parent = boundsProperty.serializedObject.FindProperty(parentPropertyPath); + SerializedProperty animationProperty = parent.FindPropertyRelative(TargetAttribute.animationField); + SerializedProperty skeletonDataProperty = parent.FindPropertyRelative(TargetAttribute.dataField); + SerializedProperty skinProperty = parent.FindPropertyRelative(TargetAttribute.skinField); + +#if !CHANGE_BOUNDS_ON_ANIMATION_CHANGE + Button updateBoundsButton = new Button(() => { + UpdateMeshBounds(boundsProperty, animationProperty.stringValue, + (SkeletonDataAsset)skeletonDataProperty.objectReferenceValue, skinProperty.stringValue); + }); + updateBoundsButton.text = "Update Bounds"; + container.Add(updateBoundsButton); +#else + referenceMeshBounds.TrackPropertyValue(animationProperty, prop => { + UpdateMeshBounds(boundsProperty, animationProperty.stringValue, + (SkeletonDataAsset)skeletonDataProperty.objectReferenceValue, skinProperty.stringValue); + }); +#endif + container.Add(referenceMeshBounds); + + container.Bind(boundsProperty.serializedObject); + return container; + } + + protected void UpdateMeshBounds (SerializedProperty boundsProperty, string boundsAnimation, + SkeletonDataAsset skeletonDataAsset, string skin) { + if (!skeletonDataAsset) + return; + + Bounds bounds = CalculateMeshBounds(boundsAnimation, skeletonDataAsset, skin); + if (bounds.extents.x == 0 || bounds.extents.y == 0) { + Debug.LogWarning("Please select different Initial Skin and Bounds Animation. Not setting reference " + + "bounds as current combination (likely no attachments visible) leads to zero Mesh bounds."); + bounds.center = Vector3.zero; + bounds.extents = Vector3.one * 2f; + } + boundsProperty.boundsValue = bounds; + boundsProperty.serializedObject.ApplyModifiedProperties(); + } + + protected Bounds CalculateMeshBounds (string animationName, SkeletonDataAsset skeletonDataAsset, string skin) { + SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false); + Skeleton skeleton = new Skeleton(skeletonData); + if (!string.IsNullOrEmpty(skin) && !string.Equals(skin, "default", System.StringComparison.Ordinal)) + skeleton.SetSkin(skin); + skeleton.SetSlotsToSetupPose(); + + Spine.Animation animation = skeletonData.FindAnimation(animationName); + if (animation != null) + animation.Apply(skeleton, -1, 0, false, null, 1.0f, MixBlend.First, MixDirection.In); + + skeleton.Update(0f); + skeleton.UpdateWorldTransform(Skeleton.Physics.Update); + + float x, y, width, height; + SkeletonClipping clipper = new SkeletonClipping(); + float[] vertexBuffer = null; + skeleton.GetBounds(out x, out y, out width, out height, ref vertexBuffer, clipper); + if (x == int.MaxValue) { + return new Bounds(); + } + + Bounds bounds = new Bounds(); + Vector2 halfSize = new Vector2(width * 0.5f, height * 0.5f); + bounds.center = new Vector3(x + halfSize.x, -y - halfSize.y, 0.0f); + bounds.extents = new Vector3(halfSize.x, halfSize.y, 0.0f); + return bounds; + } + } +} diff --git a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor/SpineVisualElementAttributeDrawers.cs.meta b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor/SpineVisualElementAttributeDrawers.cs.meta new file mode 100644 index 000000000..26a1f0bae --- /dev/null +++ b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Editor/SpineVisualElementAttributeDrawers.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: eb5762c450311694e84304e790546805 \ No newline at end of file diff --git a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Runtime/SpineVisualElement.cs b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Runtime/SpineVisualElement.cs index 04116f32a..5ab96d790 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Runtime/SpineVisualElement.cs +++ b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/Runtime/SpineVisualElement.cs @@ -29,17 +29,42 @@ using System; using Unity.Collections; -using Unity.Jobs; using UnityEngine; -using UnityEngine.Profiling; using UnityEngine.UIElements; using UIVertex = UnityEngine.UIElements.Vertex; namespace Spine.Unity { + public class BoundsFromAnimationAttribute : PropertyAttribute { + + public readonly string animationField; + public readonly string dataField; + public readonly string skinField; + + public BoundsFromAnimationAttribute (string animationField, string skinField, string dataField = "skeletonDataAsset") { + this.animationField = animationField; + this.skinField = skinField; + this.dataField = dataField; + } + } + [UxmlElement] public partial class SpineVisualElement : VisualElement { + [UxmlAttribute] + public SkeletonDataAsset SkeletonDataAsset { + get { return skeletonDataAsset; } + set { + if (skeletonDataAsset == value) return; + skeletonDataAsset = value; +#if UNITY_EDITOR + if (!Application.isPlaying) + Initialize(true); +#endif + } + } + public SkeletonDataAsset skeletonDataAsset; + [SpineAnimation(dataField: "SkeletonDataAsset", avoidGenericMenu: true)] [UxmlAttribute] public string StartingAnimation { @@ -55,7 +80,7 @@ namespace Spine.Unity { } public string startingAnimation = ""; - [SpineSkin(dataField: "SkeletonDataAsset", avoidGenericMenu: true)] + [SpineSkin(dataField: "SkeletonDataAsset", defaultAsEmptyString: true, avoidGenericMenu: true)] [UxmlAttribute] public string InitialSkinName { get { return initialSkinName; } @@ -73,19 +98,42 @@ namespace Spine.Unity { [UxmlAttribute] public bool startingLoop { get; set; } = true; [UxmlAttribute] public float timeScale { get; set; } = 1.0f; + [SpineAnimation(dataField: "SkeletonDataAsset", avoidGenericMenu: true)] [UxmlAttribute] - public SkeletonDataAsset SkeletonDataAsset { - get { return skeletonDataAsset; } + public string BoundsAnimation { + get { return boundsAnimation; } set { - if (skeletonDataAsset == value) return; - skeletonDataAsset = value; + boundsAnimation = value; #if UNITY_EDITOR - if (!Application.isPlaying) - Initialize(true); + if (!Application.isPlaying) { + if (!this.IsValid) + Initialize(true); + else { + UpdateAnimation(); + } + } #endif } } - public SkeletonDataAsset skeletonDataAsset; + public string boundsAnimation = ""; + + [UxmlAttribute] + [BoundsFromAnimation(animationField: "BoundsAnimation", + skinField: "InitialSkinName", dataField: "SkeletonDataAsset")] + public Bounds ReferenceBounds { + get { return referenceMeshBounds; } + set { + if (referenceMeshBounds == value) return; +#if UNITY_EDITOR + if (!Application.isPlaying && (value.size.x == 0 || value.size.y == 0)) return; +#endif + referenceMeshBounds = value; + if (!this.IsValid) return; + + AdjustOffsetScaleToMeshBounds(rendererElement); + } + } + public Bounds referenceMeshBounds; public AnimationState AnimationState { get { @@ -93,21 +141,22 @@ namespace Spine.Unity { return state; } } + [UxmlAttribute] public bool freeze { get; set; } + [UxmlAttribute] public bool unscaledTime { get; set; } /// Update mode to optionally limit updates to e.g. only apply animations but not update the mesh. public UpdateMode UpdateMode { get { return updateMode; } set { updateMode = value; } } protected UpdateMode updateMode = UpdateMode.FullUpdate; - protected AnimationState state; - protected Skeleton skeleton; + protected AnimationState state = null; + protected Skeleton skeleton = null; protected SkeletonRendererInstruction currentInstructions = new();// to match existing code better protected Spine.Unity.MeshGeneratorUIElements meshGenerator = new MeshGeneratorUIElements(); protected VisualElement rendererElement; IVisualElementScheduledItem scheduledItem; - protected Bounds referenceMeshBounds; protected float scale = 100; protected float offsetX, offsetY; @@ -131,6 +180,10 @@ namespace Spine.Unity { } void OnGeometryChanged (GeometryChangedEvent evt) { + if (!this.IsValid) return; + if (referenceMeshBounds.size.x == 0 || referenceMeshBounds.size.y == 0) { + AdjustReferenceMeshBounds(); + } AdjustOffsetScaleToMeshBounds(rendererElement); } @@ -154,7 +207,6 @@ namespace Spine.Unity { return; } #endif - if (freeze) return; Update(unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); rendererElement.MarkDirtyRepaint(); @@ -212,17 +264,44 @@ namespace Spine.Unity { if (!string.IsNullOrEmpty(initialSkinName)) skeleton.SetSkin(initialSkinName); - if (!string.IsNullOrEmpty(startingAnimation)) { - var animationObject = SkeletonDataAsset.GetSkeletonData(false).FindAnimation(startingAnimation); + string displayedAnimation = Application.isPlaying ? startingAnimation : boundsAnimation; + if (!string.IsNullOrEmpty(displayedAnimation)) { + var animationObject = skeletonData.FindAnimation(displayedAnimation); if (animationObject != null) { state.SetAnimation(0, animationObject, startingLoop); } } + if (referenceMeshBounds.size.x == 0 || referenceMeshBounds.size.y == 0) { + AdjustReferenceMeshBounds(); + AdjustOffsetScaleToMeshBounds(rendererElement); + } - AdjustReferenceMeshBounds(); if (scheduledItem == null) scheduledItem = schedule.Execute(Update).Every(1); + if (!Application.isPlaying) + Update(0.0f); + + rendererElement.MarkDirtyRepaint(); + } + + protected void UpdateAnimation () { + this.state.ClearTracks(); + skeleton.SetToSetupPose(); + + string displayedAnimation = Application.isPlaying ? startingAnimation : boundsAnimation; + if (!string.IsNullOrEmpty(displayedAnimation)) { + var animationObject = SkeletonDataAsset.GetSkeletonData(false).FindAnimation(displayedAnimation); + if (animationObject != null) { + state.SetAnimation(0, animationObject, startingLoop); + } + } + if (referenceMeshBounds.size.x == 0 || referenceMeshBounds.size.y == 0) { + AdjustReferenceMeshBounds(); + AdjustOffsetScaleToMeshBounds(rendererElement); + } + Update(0.0f); + rendererElement.MarkDirtyRepaint(); } @@ -320,6 +399,8 @@ namespace Spine.Unity { } public void AdjustReferenceMeshBounds () { + if (skeleton == null) + return; // Need one update to obtain valid mesh bounds Update(0.0f); @@ -332,12 +413,18 @@ namespace Spine.Unity { var submeshInstructionItem = currentInstructions.submeshInstructions.Items[i]; meshGenerator.AddSubmesh(submeshInstructionItem); } - - referenceMeshBounds = meshGenerator.GetMeshBounds(); + Bounds meshBounds = meshGenerator.GetMeshBounds(); + if (meshBounds.extents.x == 0 || meshBounds.extents.y == 0) { + ReferenceBounds = new Bounds(Vector3.zero, Vector3.one * 2f); + } else { + ReferenceBounds = meshBounds; + } } void AdjustOffsetScaleToMeshBounds (VisualElement visualElement) { Rect targetRect = visualElement.layout; + if (float.IsNaN(targetRect.width)) return; + float xScale = targetRect.width / referenceMeshBounds.size.x; float yScale = targetRect.height / referenceMeshBounds.size.y; this.scale = Math.Min(xScale, yScale); diff --git a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/package.json b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/package.json index c1e6f761b..186be6214 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/package.json +++ b/spine-unity/Modules/com.esotericsoftware.spine.ui-toolkit/package.json @@ -1,9 +1,9 @@ { "name": "com.esotericsoftware.spine.ui-toolkit", "displayName": "Spine UI Toolkit [Experimental]", - "description": "This plugin provides UI Toolkit integration for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.2.75 or newer.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", - "version": "4.2.0-preview.1", - "unity": "2023.2", + "description": "This plugin provides UI Toolkit integration for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.2.82 or newer and Unity 6000.0.16 or newer (requires [this bugfix](https://issuetracker.unity3d.com/issues/some-default-uxmlconverters-are-dependent-on-the-current-culture)).\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", + "version": "4.2.0-preview.2", + "unity": "6000.0", "author": { "name": "Esoteric Software", "email": "contact@esotericsoftware.com", @@ -11,7 +11,7 @@ }, "dependencies": { "com.unity.modules.uielements": "1.0.0", - "com.esotericsoftware.spine.spine-unity": "4.2.75" + "com.esotericsoftware.spine.spine-unity": "4.2.82" }, "keywords": [ "spine", diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Additive-URP-2D.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Additive-URP-2D.shader index 1fe8f8510..85be28e21 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Additive-URP-2D.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Additive-URP-2D.shader @@ -7,7 +7,7 @@ [MaterialToggle(_TINT_BLACK_ON)] _TintBlack("Tint Black", Float) = 0 _Black(" Dark Color", Color) = (0,0,0,0) [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 - [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default } SubShader { diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Multiply-URP-2D.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Multiply-URP-2D.shader index 17048d9e2..97a3c1302 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Multiply-URP-2D.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Multiply-URP-2D.shader @@ -7,7 +7,7 @@ [MaterialToggle(_TINT_BLACK_ON)] _TintBlack("Tint Black", Float) = 0 _Black(" Dark Color", Color) = (0,0,0,0) [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 - [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default } SubShader { diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Screen-URP-2D.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Screen-URP-2D.shader index 159d74a1e..26350562b 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Screen-URP-2D.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/BlendModes/Spine-Skeleton-Screen-URP-2D.shader @@ -7,7 +7,7 @@ [MaterialToggle(_TINT_BLACK_ON)] _TintBlack("Tint Black", Float) = 0 _Black(" Dark Color", Color) = (0,0,0,0) [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 - [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default } SubShader { diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Include/Spine-Sprite-StandardPass-URP-2D.hlsl b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Include/Spine-Sprite-StandardPass-URP-2D.hlsl index 5d43116ab..878f380b4 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Include/Spine-Sprite-StandardPass-URP-2D.hlsl +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Include/Spine-Sprite-StandardPass-URP-2D.hlsl @@ -109,7 +109,8 @@ half4 CombinedShapeLightFragment(VertexOutputSpriteURP2D input) : SV_Target #endif half4 mask = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, input.texcoord.xy); - main.rgb = main.a == 0 ? main.rgb : main.rgb / main.a; // un-premultiply for additive lights in CombinedShapeLightShared, reapply afterwards + // un-premultiply for additive lights in CombinedShapeLightShared, reapply afterwards + main.rgb = main.a < 0.001 ? main.rgb : main.rgb / main.a; // < epsilon prevents imprecision issues on some HW. #if UNITY_VERSION < 202120 half4 pixel = half4(CombinedShapeLightShared(half4(main.rgb, 1), mask, input.lightingUV).rgb * main.a, main.a); #else diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-SkeletonLit-URP-2D.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-SkeletonLit-URP-2D.shader index 2d59239bf..a3c0885b1 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-SkeletonLit-URP-2D.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/2D/Spine-SkeletonLit-URP-2D.shader @@ -139,7 +139,7 @@ Shader "Universal Render Pipeline/2D/Spine/Skeleton Lit" { return main; #endif // un-premultiply for additive lights in CombinedShapeLightShared, reapply afterwards - main.rgb = main.a == 0 ? main.rgb : main.rgb / main.a; + main.rgb = main.a < 0.001 ? main.rgb : main.rgb / main.a; #else #if !defined(_LIGHT_AFFECTS_ADDITIVE) if (i.color.a == 0) { @@ -149,10 +149,10 @@ Shader "Universal Render Pipeline/2D/Spine/Skeleton Lit" { #if !defined(_STRAIGHT_ALPHA_INPUT) // un-premultiply for additive lights in CombinedShapeLightShared, reapply afterwards - tex.rgb = tex.a == 0 ? tex.rgb : tex.rgb / tex.a; + tex.rgb = tex.a < 0.001 ? tex.rgb : tex.rgb / tex.a; // < epsilon prevents imprecision issues on some HW. #endif half4 main = tex * i.color; - #endif + #endif half4 mask = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, i.uv); #if UNITY_VERSION < 202120 return half4(CombinedShapeLightShared(half4(main.rgb, 1), mask, i.lightingUV).rgb * main.a, main.a); diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Additive-URP.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Additive-URP.shader index a99c16785..e85d7b96a 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Additive-URP.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Additive-URP.shader @@ -7,7 +7,7 @@ [MaterialToggle(_TINT_BLACK_ON)] _TintBlack("Tint Black", Float) = 0 _Black(" Dark Color", Color) = (0,0,0,0) [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 - [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default } SubShader { @@ -63,6 +63,44 @@ ENDHLSL } - UsePass "Universal Render Pipeline/Spine/Skeleton/SHADOWCASTER" + // UsePass "Universal Render Pipeline/Spine/Skeleton/SHADOWCASTER" + // Note: UsePass above fails when both main and additional lights are disabled, thus inlined below. + Pass + { + Name "ShadowCaster" + Tags{"LightMode" = "ShadowCaster"} + + ZWrite On + ColorMask 0 + ZTest LEqual + Cull Off + + HLSLPROGRAM + // Required to compile gles 2.0 with standard srp library + #pragma prefer_hlslcc gles + #pragma exclude_renderers d3d11_9x + #pragma target 2.0 + + // ------------------------------------- + // Material Keywords + #pragma shader_feature _ALPHATEST_ON + + //-------------------------------------- + // GPU Instancing + #pragma multi_compile_instancing + #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + + #pragma vertex ShadowPassVertexSkeletonLit + #pragma fragment ShadowPassFragmentSkeletonLit + + #define USE_URP + #define fixed4 half4 + #define fixed3 half3 + #define fixed half + #include "../Include/Spine-Input-URP.hlsl" + #include "../Include/Spine-SkeletonLit-ShadowCasterPass-URP.hlsl" + + ENDHLSL + } } } diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Multiply-URP.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Multiply-URP.shader index 80302211d..a250333b9 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Multiply-URP.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Multiply-URP.shader @@ -7,7 +7,7 @@ [MaterialToggle(_TINT_BLACK_ON)] _TintBlack("Tint Black", Float) = 0 _Black(" Dark Color", Color) = (0,0,0,0) [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 - [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default } SubShader { @@ -63,6 +63,44 @@ ENDHLSL } - UsePass "Universal Render Pipeline/Spine/Skeleton/SHADOWCASTER" + // UsePass "Universal Render Pipeline/Spine/Skeleton/SHADOWCASTER" + // Note: UsePass above fails when both main and additional lights are disabled, thus inlined below. + Pass + { + Name "ShadowCaster" + Tags{"LightMode" = "ShadowCaster"} + + ZWrite On + ColorMask 0 + ZTest LEqual + Cull Off + + HLSLPROGRAM + // Required to compile gles 2.0 with standard srp library + #pragma prefer_hlslcc gles + #pragma exclude_renderers d3d11_9x + #pragma target 2.0 + + // ------------------------------------- + // Material Keywords + #pragma shader_feature _ALPHATEST_ON + + //-------------------------------------- + // GPU Instancing + #pragma multi_compile_instancing + #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + + #pragma vertex ShadowPassVertexSkeletonLit + #pragma fragment ShadowPassFragmentSkeletonLit + + #define USE_URP + #define fixed4 half4 + #define fixed3 half3 + #define fixed half + #include "../Include/Spine-Input-URP.hlsl" + #include "../Include/Spine-SkeletonLit-ShadowCasterPass-URP.hlsl" + + ENDHLSL + } } } diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Screen-URP.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Screen-URP.shader index 2e200e3c6..5b16e5f93 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Screen-URP.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/BlendModes/Spine-Skeleton-Screen-URP.shader @@ -7,7 +7,7 @@ [MaterialToggle(_TINT_BLACK_ON)] _TintBlack("Tint Black", Float) = 0 _Black(" Dark Color", Color) = (0,0,0,0) [HideInInspector] _StencilRef("Stencil Reference", Float) = 1.0 - [HideInInspector][Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default + [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Comparison", Float) = 8 // Set to Always as default } SubShader { @@ -63,6 +63,44 @@ ENDHLSL } - UsePass "Universal Render Pipeline/Spine/Skeleton/SHADOWCASTER" + // UsePass "Universal Render Pipeline/Spine/Skeleton/SHADOWCASTER" + // Note: UsePass above fails when both main and additional lights are disabled, thus inlined below. + Pass + { + Name "ShadowCaster" + Tags{"LightMode" = "ShadowCaster"} + + ZWrite On + ColorMask 0 + ZTest LEqual + Cull Off + + HLSLPROGRAM + // Required to compile gles 2.0 with standard srp library + #pragma prefer_hlslcc gles + #pragma exclude_renderers d3d11_9x + #pragma target 2.0 + + // ------------------------------------- + // Material Keywords + #pragma shader_feature _ALPHATEST_ON + + //-------------------------------------- + // GPU Instancing + #pragma multi_compile_instancing + #pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + + #pragma vertex ShadowPassVertexSkeletonLit + #pragma fragment ShadowPassFragmentSkeletonLit + + #define USE_URP + #define fixed4 half4 + #define fixed3 half3 + #define fixed half + #include "../Include/Spine-Input-URP.hlsl" + #include "../Include/Spine-SkeletonLit-ShadowCasterPass-URP.hlsl" + + ENDHLSL + } } } diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Common-URP.hlsl b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Common-URP.hlsl index 21c062e23..69f7b9985 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Common-URP.hlsl +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Common-URP.hlsl @@ -14,6 +14,12 @@ #endif #if IS_URP_14_OR_NEWER && !defined(_USE_WEBGL1_LIGHTS) #define IS_URP_15_OR_NEWER 1 + #include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl" + #if defined(_APVWorldOffset) + #define IS_URP_17_OR_NEWER 1 + #else + #define IS_URP_17_OR_NEWER 0 + #endif #else #define IS_URP_15_OR_NEWER 0 #endif diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Skeleton-ForwardPass-URP.hlsl b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Skeleton-ForwardPass-URP.hlsl index 53ef8be8e..f6f895ac4 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Skeleton-ForwardPass-URP.hlsl +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Skeleton-ForwardPass-URP.hlsl @@ -49,6 +49,9 @@ VertexOutput vert(appdata v) { half4 frag(VertexOutput i) : SV_Target{ float4 texColor = tex2D(_MainTex, i.uv0); +#if defined(_ZWRITE) + clip(texColor.a * i.color.a - _Cutoff); +#endif #if defined(_TINT_BLACK_ON) return fragTintedColor(texColor, i.darkColor, i.color, _Color.a, _Black.a); #else diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl index 1dcb508d1..f1f5551aa 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-SkeletonLit-ForwardPass-URP.hlsl @@ -149,7 +149,12 @@ VertexOutput vert(appdata v) { half3 vertexSH; #if IS_URP_15_OR_NEWER #ifdef OUTPUT_SH4 - OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), vertexSH); + #if IS_URP_17_OR_NEWER + float4 ignoredProbeOcclusion; + OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), vertexSH, ignoredProbeOcclusion); + #else // 15 or newer + OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), vertexSH); + #endif #else OUTPUT_SH(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), vertexSH); #endif diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl index fe5c3198f..aa2cc4bd5 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Include/Spine-Sprite-ForwardPass-URP.hlsl @@ -313,7 +313,12 @@ VertexOutputLWRP ForwardPassVertexSprite(VertexInput input) #if IS_URP_15_OR_NEWER #ifdef OUTPUT_SH4 - OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH); + #if IS_URP_17_OR_NEWER + float4 ignoredProbeOcclusion; + OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH, ignoredProbeOcclusion); + #else // 15 or newer + OUTPUT_SH4(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH); + #endif #else OUTPUT_SH(positionWS, normalWS.xyz, GetWorldSpaceNormalizeViewDir(positionWS), output.vertexSH); #endif diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Skeleton-URP.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Skeleton-URP.shader index 4853d605a..b2d76acfb 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Skeleton-URP.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Spine-Skeleton-URP.shader @@ -51,6 +51,7 @@ Shader "Universal Render Pipeline/Spine/Skeleton" { // Spine related keywords #pragma shader_feature _ _STRAIGHT_ALPHA_INPUT #pragma shader_feature _TINT_BLACK_ON + #pragma shader_feature _ZWRITE #pragma vertex vert #pragma fragment frag diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json index 9b3bae1f1..1d0dc3154 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/package.json @@ -2,7 +2,7 @@ "name": "com.esotericsoftware.spine.urp-shaders", "displayName": "Spine Universal RP Shaders", "description": "This plugin provides universal render pipeline (URP) shaders for the spine-unity runtime.\n\nPrerequisites:\nIt requires a working installation of the spine-unity runtime, version 4.2.\n(See http://esotericsoftware.com/git/spine-runtimes/spine-unity)", - "version": "4.2.33", + "version": "4.2.38", "unity": "2019.3", "author": { "name": "Esoteric Software",