@galacean/engine-spine 1.1.0-test.1 → 2.0.0-alpha.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +158 -44
  3. package/dist/browser.js +2139 -1
  4. package/dist/browser.js.map +1 -0
  5. package/dist/browser.min.js +2 -0
  6. package/dist/browser.min.js.map +1 -0
  7. package/dist/main.js +2134 -1
  8. package/dist/main.js.map +1 -1
  9. package/dist/module.js +2117 -1
  10. package/dist/module.js.map +1 -1
  11. package/package.json +30 -55
  12. package/types/SpineAnimation.d.ts +4 -44
  13. package/types/SpineAnimationState.d.ts +32 -0
  14. package/types/SpineAnimationStateData.d.ts +10 -0
  15. package/types/SpineAnimationStateListener.d.ts +20 -0
  16. package/types/SpineBone.d.ts +28 -0
  17. package/types/SpineConstant.d.ts +12 -0
  18. package/types/SpinePhysics.d.ts +17 -0
  19. package/types/SpinePhysicsConstraint.d.ts +22 -0
  20. package/types/SpineSkeleton.d.ts +31 -0
  21. package/types/SpineSkeletonData.d.ts +18 -0
  22. package/types/SpineSkin.d.ts +7 -0
  23. package/types/SpineSlot.d.ts +13 -0
  24. package/types/SpineTrackEntry.d.ts +44 -0
  25. package/types/enums/SpineBlendMode.d.ts +14 -0
  26. package/types/index.d.ts +15 -9
  27. package/types/loader/LoaderUtils.d.ts +1 -0
  28. package/types/loader/SpineLoader.d.ts +21 -0
  29. package/types/loader/SpineResource.d.ts +37 -0
  30. package/types/loader/SpineVersion.d.ts +2 -0
  31. package/types/loader/index.d.ts +2 -0
  32. package/types/renderer/SpineAnimationRenderer.d.ts +142 -0
  33. package/types/renderer/SpineGeometry.d.ts +1 -0
  34. package/types/renderer/SpineMaterial.d.ts +10 -0
  35. package/types/renderer/index.d.ts +2 -0
  36. package/types/runtime/ISpineRuntime.d.ts +4 -0
  37. package/dist/miniprogram.js +0 -1
  38. package/types/SpineLoader.d.ts +0 -33
  39. package/types/SpineMaterial.d.ts +0 -6
  40. package/types/SpineRenderer.d.ts +0 -38
  41. package/types/core/MeshGenerator.d.ts +0 -42
  42. package/types/core/SpineMesh.d.ts +0 -11
  43. package/types/spine-core/Animation.d.ts +0 -378
  44. package/types/spine-core/AnimationState.d.ts +0 -365
  45. package/types/spine-core/AnimationStateData.d.ts +0 -23
  46. package/types/spine-core/AssetManager.d.ts +0 -36
  47. package/types/spine-core/AtlasAttachmentLoader.d.ts +0 -23
  48. package/types/spine-core/BlendMode.d.ts +0 -7
  49. package/types/spine-core/Bone.d.ts +0 -110
  50. package/types/spine-core/BoneData.d.ts +0 -44
  51. package/types/spine-core/ConstraintData.d.ts +0 -7
  52. package/types/spine-core/Event.d.ts +0 -16
  53. package/types/spine-core/EventData.d.ts +0 -13
  54. package/types/spine-core/IkConstraint.d.ts +0 -38
  55. package/types/spine-core/IkConstraintData.d.ts +0 -26
  56. package/types/spine-core/PathConstraint.d.ts +0 -46
  57. package/types/spine-core/PathConstraintData.d.ts +0 -52
  58. package/types/spine-core/SharedAssetManager.d.ts +0 -19
  59. package/types/spine-core/Skeleton.d.ts +0 -134
  60. package/types/spine-core/SkeletonBinary.d.ts +0 -49
  61. package/types/spine-core/SkeletonBounds.d.ts +0 -48
  62. package/types/spine-core/SkeletonClipping.d.ts +0 -22
  63. package/types/spine-core/SkeletonData.d.ts +0 -89
  64. package/types/spine-core/SkeletonJson.d.ts +0 -34
  65. package/types/spine-core/Skin.d.ts +0 -43
  66. package/types/spine-core/Slot.d.ts +0 -42
  67. package/types/spine-core/SlotData.d.ts +0 -23
  68. package/types/spine-core/Texture.d.ts +0 -46
  69. package/types/spine-core/TextureAtlas.d.ts +0 -30
  70. package/types/spine-core/TransformConstraint.d.ts +0 -36
  71. package/types/spine-core/TransformConstraintData.d.ts +0 -34
  72. package/types/spine-core/Triangulator.d.ts +0 -14
  73. package/types/spine-core/Updatable.d.ts +0 -9
  74. package/types/spine-core/Utils.d.ts +0 -124
  75. package/types/spine-core/VertexEffect.d.ts +0 -7
  76. package/types/spine-core/attachments/Attachment.d.ts +0 -43
  77. package/types/spine-core/attachments/AttachmentLoader.d.ts +0 -25
  78. package/types/spine-core/attachments/AttachmentType.d.ts +0 -9
  79. package/types/spine-core/attachments/BoundingBoxAttachment.d.ts +0 -12
  80. package/types/spine-core/attachments/ClippingAttachment.d.ts +0 -14
  81. package/types/spine-core/attachments/MeshAttachment.d.ts +0 -46
  82. package/types/spine-core/attachments/PathAttachment.d.ts +0 -19
  83. package/types/spine-core/attachments/PointAttachment.d.ts +0 -20
  84. package/types/spine-core/attachments/RegionAttachment.d.ts +0 -88
  85. package/types/spine-core/polyfills.d.ts +0 -3
  86. package/types/spine-core/vertexeffects/JitterEffect.d.ts +0 -11
  87. package/types/spine-core/vertexeffects/SwirlEffect.d.ts +0 -16
  88. package/types/types.d.ts +0 -4
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
- The MIT License (MIT)
1
+ The MIT License
2
2
 
3
- Copyright (c) 木鳐 <zhubei.zb@antgroup.com> (Ant Financial)
3
+ Copyright (c) 2020 - present Ant Group
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,79 +1,193 @@
1
+ # Spine integration
2
+
3
+ Application code uses `SpineResource` and `SpineAnimationRenderer` from `@galacean/engine-spine`. Install the backend matching your assets and pass one runtime instance when creating the engine. Import `engine-spine` before engine creation so its loader receives the configuration:
4
+
5
+ ```ts
6
+ import { WebGLEngine } from "@galacean/engine";
7
+ import { Spine38Runtime } from "@galacean/engine-spine-core-3.8";
8
+ import { SpineResource, SpineAnimationRenderer } from "@galacean/engine-spine";
9
+
10
+ const engine = await WebGLEngine.create({
11
+ canvas: "canvas",
12
+ spine: new Spine38Runtime()
13
+ });
14
+ const resource = await engine.resourceManager.load<SpineResource>({
15
+ url: "character.json",
16
+ type: "Spine"
17
+ });
18
+ const character = resource.instantiate();
19
+ engine.sceneManager.activeScene.addRootEntity(character);
20
+ const renderer = character.getComponent(SpineAnimationRenderer);
21
+ renderer.state.setAnimation(0, "idle", true);
22
+ renderer.skeleton.setSkinByName("winter");
23
+ renderer.skeleton.setSlotsToSetupPose();
24
+ ```
1
25
 
26
+ The loader reads the JSON or binary export header before parsing the skeleton. Its major/minor version selects a backend registered for that engine, and the resource retains that backend alongside the parsed data. Instances and clones use the resource's backend to create independent skeleton poses and animation states. Assigning another resource to a renderer recreates these states with the resource's backend.
2
27
 
3
- # Galacean Engine spine runtime
4
- ![Jun-12-2021 18-37-22.gif](https://gw.alipayobjects.com/mdn/mybank_yul/afts/img/A*am1ySYTDBQAAAAAAAAAAAAAAARQnAQ)
28
+ The backend configuration belongs to each engine; configuring one engine does not configure another. Application code configures the backend through engine creation. Runtime registration is an internal integration detail.
5
29
 
30
+ An application using only 3.8 installs and configures only the 3.8 backend. Neither the shared package nor the 3.8 backend depends on the 4.2 runtime. Importing a backend alone does not register it. Missing versions fail explicitly; the loader does not download missing backends or fall back to another version.
6
31
 
7
- ![](https://img.shields.io/npm/v/@galacean/engine-spine#id=QfHW0&originHeight=20&originWidth=80&originalType=binary&ratio=1&status=done&style=none)
8
- ![](https://img.shields.io/bundlephobia/minzip/@galacean/engine-spine#id=yUnp4&originHeight=20&originWidth=144&originalType=binary&ratio=1&status=done&style=none)
9
- ![](https://img.shields.io/npm/dm/@galacean/engine-spine#id=lqs8U&originHeight=20&originWidth=134&originalType=binary&ratio=1&status=done&style=none)
32
+ Only `.skel` selects the Spine loader automatically; `.json` and `.bin` require `type: "Spine"`. Skeleton content may be JSON or Spine binary data regardless of extension. For a single URL, explicit atlas dependencies take precedence; otherwise the loader derives a sibling `.atlas` path without inheriting the skeleton URL's query or fragment. Use `urls` to supply an atlas URL with its own query parameters. Textures resolve from atlas page names unless explicit URLs or asset dependencies provide them.
10
33
 
11
- ---
34
+ ## Public API
12
35
 
36
+ Use `SpineResource` and `SpineAnimationRenderer` to access skeletons, bones, slots, skins and animation playback. These objects are shared across supported asset versions. Load resources through the resource manager; `renderer.skeleton` and `renderer.state` require a bound resource.
13
37
 
38
+ `skeleton.findSlot(name)` returns a `SpineSlot`, or `null` if the name is missing. The same slot object is reused across lookups, animation updates and skin changes. `skeleton.slots` lists slots in setup order; `slot.bone` is the corresponding object from `skeleton.bones`. Slots belong to each skeleton instance.
14
39
 
15
- Spine runtime for [Galacean engine](https://github.com/galacean/engine).
16
- ##
17
- ## Usage
40
+ ```ts
41
+ const weapon = renderer.skeleton.findSlot("weapon");
42
+ if (weapon) {
43
+ weapon.setAttachment("sword"); // Attachment entry in the current skin, falling back to the default skin.
44
+ weapon.setAttachment(null); // Hide this slot's attachment.
45
+ weapon.setToSetupPose(); // Restore its setup color and attachment using the current skin.
46
+ }
47
+ ```
18
48
 
49
+ Use `resource.createSkin(name)` to compose skins from the same resource. Skeleton data, skins and mixing configuration are shared across instances. Each instance has its own pose and playback state.
19
50
 
20
- ```typescript
21
- import { SpineAnimation } from '@galacean/engine-spine';
51
+ ## Playback and time
22
52
 
23
- // init oasis
24
- addSpine();
53
+ The renderer updates automatically. Keep Spine's track and queue APIs to arrange animations:
25
54
 
26
- async function addSpine() {
27
- const spineEntity = await engine.resourceManager.load(
28
- {
29
- url: 'https://sbfkcel.github.io/pixi-spine-debug/assets/spine/spineboy-pro.json',
30
- type: 'spine',
31
- },
32
- );
33
- rootEntity.addChild(spineEntity);
34
- const spineAnimation = spineEntity.getComponent(SpineAnimation);
35
- spineAnimation.state.setAnimation(0, 'walk', true);
36
- }
55
+ ```ts
56
+ resource.stateData.defaultMix = 0.2; // Shared mixing configuration.
57
+ const state = renderer.state;
58
+ state.setAnimation(0, "attack", false);
59
+ state.addAnimation(0, "idle", true, 0);
37
60
  ```
38
61
 
62
+ `renderer.timeScale` defaults to 1 and scales both animation and skeleton time, including 4.2 physics. Zero stops time advancement but continues applying the pose and drawing, so skin changes and explicit track-time edits still appear. Restore the previous multiplier to resume:
39
63
 
40
- ## npm
41
- ```sh
42
- npm install @galacean-engine/spine
64
+ ```ts
65
+ renderer.timeScale = 0.5;
66
+ const previousTimeScale = renderer.timeScale;
67
+ renderer.timeScale = 0;
68
+ renderer.timeScale = previousTimeScale;
43
69
  ```
44
70
 
71
+ The native `state.timeScale` and `entry.timeScale` remain independent animation controls. Relative to the engine's delta time, a track advances by `renderer.timeScale * state.timeScale * entry.timeScale`; mixing advances by `renderer.timeScale * state.timeScale`, and skeleton physics by `renderer.timeScale`. Changing an entry's `trackTime` selects an animation time on the next update; it does not seek physics history.
72
+
73
+ ## Pose update signals
74
+
75
+ Use renderer signals to modify or read the current frame's pose at a defined stage:
76
+
77
+ | Signal | Timing and purpose |
78
+ | --- | --- |
79
+ | `onBeforeApply` | After time advances, before animation application; prepare the base pose. |
80
+ | `onUpdateLocal` | After animation application, before constraints and world transforms; edit local bone values. |
81
+ | `onUpdateWorld` | After a preliminary pose solve; read world values to adjust local values before the final solve. |
82
+ | `onUpdateComplete` | After the final solve, before geometry generation; read the final bone transforms. |
83
+
84
+ ```ts
85
+ const aim = (source: SpineAnimationRenderer) => {
86
+ const head = source.skeleton.findBone("head");
87
+ if (head) head.rotation += 15;
88
+ };
89
+ renderer.onUpdateLocal.on(aim);
90
+ // Remove when the behavior is no longer needed:
91
+ renderer.onUpdateLocal.off(aim);
92
+ ```
45
93
 
94
+ Signals run synchronously in this order, including when `renderer.timeScale` is zero. `onUpdateWorld` adds a preliminary solve only while it has listeners; 4.2 uses the existing physics pose for this solve and advances simulation only in the final solve. Bone world values are in skeleton space; apply the entity's world transform when positioning scene objects. Changing local bone values in `onUpdateComplete` does not trigger another solve.
46
95
 
96
+ Pose updates still run in the renderer update phase, after scripts' `onLateUpdate`. Signals belong to the renderer and survive resource changes; read its current skeleton in callbacks. Destroying the renderer removes the listeners. Cloning follows `Signal` rules: component/method bindings are remapped, while function listeners are not copied.
47
97
 
48
- ## Version
49
- @galacean/engine-spine currently only supports spine version 3.8
98
+ ## Materials
99
+
100
+ Renderers in the same engine initially share one default `SpineMaterial`. Set or instance this material using the standard renderer API. It is used by slots without a material override and remains assigned through animation updates, skin changes and resource rebinding. Dynamic batch indices are not material slots.
101
+
102
+ ```ts
103
+ import { SpineMaterial } from "@galacean/engine-spine";
104
+
105
+ const material = new SpineMaterial(engine, customShader);
106
+ renderer.setMaterial(material);
107
+ // Or get an independent copy of the current material:
108
+ const instance = renderer.getInstanceMaterial();
109
+ ```
110
+
111
+ Use a `SpineSlot` to override the material for part of a character:
112
+
113
+ ```ts
114
+ const weapon = renderer.skeleton.findSlot("weapon");
115
+ if (weapon) {
116
+ renderer.setMaterial(weapon, weaponMaterial);
117
+ renderer.getMaterial(weapon); // Effective material: the override, or the renderer's default.
118
+ renderer.setMaterial(weapon, null); // Remove the override.
119
+ }
120
+ ```
50
121
 
122
+ `setMaterial(material)` and `setMaterial(0, material)` set the default material. Numeric indices retain their renderer material-array meaning; they do not identify Spine slots. `getMaterials()` and `getInstanceMaterial()` retain their inherited material-array behavior. Slot overrides are independent of this array. With a null default material, only slots with an override render.
51
123
 
52
- ## Feature
124
+ Overrides survive skin, attachment and draw-order changes. Clones retain the material references and apply them to their own slots. Changing or clearing the resource removes the overrides; a slot from another instance or an old resource binding is rejected. Adjacent attachments batch together only when their effective material, texture and blend mode match.
53
125
 
54
- - Simple in usage
55
- - High performance.
56
- - Intergrated with galacean engine.
57
- - Component based API.
126
+ A custom shader consumes the Spine vertex layout (`POSITION`, `LIGHT_COLOR`, `TEXCOORD_0`, and `DARK_COLOR` when enabled) and these inputs:
58
127
 
128
+ | Scope | Input |
129
+ | --- | --- |
130
+ | Renderer macro | `RENDERER_TINT_BLACK` |
131
+ | Batch texture | `renderElement_SpineTexture` |
132
+ | Batch blend factors | `renderElement_SpineSourceColorBlendFactor`, `renderElement_SpineDestinationColorBlendFactor`, `renderElement_SpineSourceAlphaBlendFactor`, `renderElement_SpineDestinationAlphaBlendFactor` |
59
133
 
134
+ Textures and vertex colors use straight alpha. Vertex colors are sRGB values; decode them to linear space before tinting. Sample the atlas with `texture2DSRGB`. Premultiply the final linear RGB by the final alpha before output when using the supplied batch blend factors. The built-in shader follows this contract for normal, additive, multiply and screen blending.
60
135
 
61
- ## Contributing
62
- Everyone is welcome to join us! Whether you find a bug, have a great feature request or you fancy owning a task from the road map feel free to get in touch.
63
- ​
136
+ The built-in `2D/Spine` pass binds its blend state to the batch factors. Custom passes can bind these same variables to preserve Spine's blend modes, or declare their own fixed state. Spine does not overwrite a pass's state. User parameters remain on the original material; no hidden material copies need synchronizing. Renderer macros and batch textures do not mutate shared materials.
64
137
 
65
- Make sure to read the [Contributing Guide](.github/HOW_TO_CONTRIBUTE.md) before submitting changes.
138
+ ## Atlas textures
66
139
 
140
+ Spine uses the engine's linear rendering workflow and requires **straight-alpha sRGB textures**. In Spine's Texture Packer settings, disable **Premultiply alpha** and enable **Bleed**. Bleed fills transparent pixels with neighboring colors without changing alpha, reducing dark edges during texture filtering. The shader still premultiplies its final linear output for blending; input textures must not be premultiplied.
67
141
 
68
- ## Links
142
+ The loader rejects any atlas page marked `pma: true`, with the page name and export instructions. Older atlases without `pma` are assumed to contain straight-alpha textures; the loader cannot infer encoding from pixels. Re-export legacy PMA images rather than just changing the flag. There is no alpha-mode override or renderer PMA switch.
69
143
 
70
- - [Examples](https://oasisengine.cn/#/examples/latest/spine-animation)
71
- - [Documentation](https://oasisengine.cn/#/docs/latest/cn/spine)
72
- - [GalaceanEngine](https://oasisengine.cn/)
144
+ Ordinary images use the texture loader's default `isSRGBColorSpace: true`. For `.tex` and compressed textures, enable sRGB in the exported texture. A texture already loaded without sRGB sampling is rejected instead of modifying a shared resource. Configure textures before their first load: ResourceManager caches by URL. Generate compression and mipmaps from the straight-alpha image with color bleed.
73
145
 
146
+ Textures use the existing loading, sharing and content restoration path. Spine does not read back pixels or create conversion textures.
74
147
 
148
+ ### Editor migration
75
149
 
76
- ## License
150
+ The editor upgrade is separate from this engine change. Re-export existing PMA assets as straight alpha with color bleed, enable sRGB on their textures, and emit `pma: false` (or omit `pma`). Remove the serialized component-level `premultipliedAlpha` field. For legacy assets without metadata, check their original export settings; deleting the old component flag does not convert their pixels.
77
151
 
152
+ Load the skeleton and atlas dependencies through the registered Spine loader to obtain a `SpineResource`. The editor should stop constructing the old library's `SkeletonData`, `TextureAtlas` and `SpineResource` directly. Applications and custom shaders should remove the old renderer PMA property/uniform and follow the material contract above.
78
153
 
79
- The Oasis Engine is released under the [MIT](https://opensource.org/licenses/MIT) license. See LICENSE file.
154
+ ## Physics
155
+
156
+ Physics is an explicit capability, including on backends that do not support it:
157
+
158
+ ```ts
159
+ const physics = renderer.physics; // null before an asset is bound
160
+ if (physics?.supported) {
161
+ physics.value.physicsTranslate(1, 0);
162
+ for (const constraint of physics.value.physicsConstraints) constraint.reset();
163
+ } else if (physics) {
164
+ console.log(physics.reason); // e.g. Spine 3.8 does not support physics constraints
165
+ }
166
+ ```
167
+
168
+ A supported capability with an empty constraint list is different from an unsupported capability. Physics constraints belong to the skeleton and are evaluated by its backend, together with the other constraints. They are not an independent physics world.
169
+
170
+ ## Resource lifetime
171
+
172
+ Use `state.addAnimation` for a known playback sequence, and `entry.listener` for callbacks belonging to one playback. Playback commands finish configuring and wrapping their entries before dispatching callbacks; callbacks remain synchronous and are not deferred to another frame. The returned entry and callback arguments have the same identity.
173
+
174
+ Completion callbacks can replace or enqueue animations, or destroy the effect entity. Disposal notifications run while their entries are still readable, then those entries become invalid. Internal listener cleanup waits for the active command or animation update to finish dispatching. A renderer whose resource binding ended during a callback does not submit the old binding's geometry.
175
+
176
+ Entities instantiated from a resource keep it alive. The resource retains textures referenced by all skins, attachments and sequence frames, including those not currently drawn. Destroying the resource releases its internal entity template and rendering resources.
177
+
178
+ Live renderer references protect shared or user-assigned materials. Unreferenced materials participate in `ResourceManager.gc()`. Destroying one renderer does not destroy a material still used by another.
179
+
180
+ ## Backend integration
181
+
182
+ The shared package registers the Spine loader. Version packages export their runtime adapter classes for engine configuration; native Spine classes are not re-exported from their package roots. Backend authors implement the contracts in `@galacean/engine-design`. Backends calculate world vertices and perform native clipping, then submit attachment geometry through `ISpineGeometry`. The shared layer owns the final vertex layout, index offsets, bounds and ordered draw batches, along with GPU buffers and materials. Input arrays and output buffers are reused.
183
+
184
+ The 3.8 backend vendors runtime sources because the official `@esotericsoftware/spine-core` npm package has no 3.8 release. The 4.2 backend consumes the official npm package. Both backend builds bundle their native runtime code; this source-distribution difference does not change the public API or registration model.
185
+
186
+ For script/UMD builds, load the engine, shared Spine bundle and required version bundles before creating the engine:
187
+
188
+ ```js
189
+ const engine = await Galacean.WebGLEngine.create({
190
+ canvas: "canvas",
191
+ spine: new Galacean.SpineCore38.Spine38Runtime()
192
+ });
193
+ ```