diff --git a/CHANGELOG.md b/CHANGELOG.md index d3d695cea..40be0079d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -169,6 +169,12 @@ - SkeletonMecanim: Added `Scene Preview` option to preview an Animation Clip for e.g. easier event placement. When enabled, the Animation Clip selected in the Animation window is previewed in the Scene and Game views. Lock the `SkeletonMecanim` Inspector window, open the Animation window and select the Animation Clip. Then in the Animation window scrub through the timeline to see the current animation frame previewed. - `Universal Render Pipeline/Spine/Skeleton Lit` shader now supports [Adaptive Probe Volumes (APV)](https://docs.unity3d.com/6000.0/Documentation/Manual/urp/probevolumes-concept.html) introduced in Unity 6. The shader also provides a new material property `APV per Pixel` to either calculate APV lighting contribution per pixel (the default) or per vertex. - `Universal Render Pipeline/Spine/Sprite` shader now also supports [Adaptive Probe Volumes (APV)](https://docs.unity3d.com/6000.0/Documentation/Manual/urp/probevolumes-concept.html) introduced in Unity 6. APV lighting contribution is automatically calculated per pixel. + - All Spine Outline shaders, including the URP outline shaders, now provide an additional parameter `Fill`. Enable it to also fill the opaque area inside the outline with the outline color. Prevents a semi-transparent gap between outline and skeleton. Defaults to `disabled` to maintain existing behaviour. + - Added example component `RenderExistingMeshGraphic` (similar to `RenderExistingMesh`) to render a `SkeletonGraphic` mesh again with different materials. This might be required by e.g. URP and SkeletonGraphic outline shaders skipping additional render passes. To add a second outline variant of your SkeletonGraphic: + 1. Add a GameObject at the same hierarchy level as the reference SkeletonGraphic and move it before the reference SkeletonGraphic to render behind. + 2. Add a `RenderExistingMeshGraphic` component. + 3. In the `RenderExistingMeshGraphic` component Inspector at `Reference Skeleton Graphic` assign the original `SkeletonGraphic` object. + 4. At `Replacement Material` assign e.g. the included _SkeletonGraphicDefaultOutline_ material to replace all materials with this material. Alternatively, if `Multiple CanvasRenderers` is enabled at the reference SkeletonGraphic, you can add entries to the `Replacement Materials` list and at each entry assign the original SkeletonGraphic material (e.g. _SkeletonGraphicDefault_) to be replaced and the respective `Replacement Material` (e.g. _SkeletonGraphicDefaultOutline_). - **Breaking changes** diff --git a/spine-c/spine-c/src/spine/SkeletonBinary.c b/spine-c/spine-c/src/spine/SkeletonBinary.c index 28a4b9fd3..a151c48eb 100644 --- a/spine-c/spine-c/src/spine/SkeletonBinary.c +++ b/spine-c/spine-c/src/spine/SkeletonBinary.c @@ -1341,9 +1341,9 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const } else { if (!string_starts_with(skeletonData->version, SPINE_VERSION_STRING)) { FREE(input); - spSkeletonData_dispose(skeletonData); char errorMsg[255]; snprintf(errorMsg, 255, "Skeleton version %s does not match runtime version %s", skeletonData->version, SPINE_VERSION_STRING); + spSkeletonData_dispose(skeletonData); _spSkeletonBinary_setError(self, errorMsg, NULL); return NULL; } diff --git a/spine-godot/spine_godot/SpineAtlasResource.cpp b/spine-godot/spine_godot/SpineAtlasResource.cpp index 0e59817ae..9ae73db0b 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.cpp +++ b/spine-godot/spine_godot/SpineAtlasResource.cpp @@ -217,8 +217,6 @@ void SpineAtlasResource::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_path"), "", "get_source_path"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures"), "", "get_textures"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "normal_maps"), "", "get_normal_maps"); - - ADD_SIGNAL(MethodInfo("skeleton_atlas_changed")); } SpineAtlasResource::SpineAtlasResource() : atlas(nullptr), texture_loader(nullptr), normal_map_prefix("n") { diff --git a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp index 73e594db3..d65575a4f 100644 --- a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp @@ -32,10 +32,26 @@ #ifdef SPINE_GODOT_EXTENSION #include +#include +#include #else +#if VERSION_MAJOR > 3 +#include "core/config/engine.h" +#include "editor/editor_interface.h" +#else +#include "core/engine.h" +#endif #include #endif +#ifdef TOOLS_ENABLED +#ifdef SPINE_GODOT_EXTENSION +#include +#else +#include "editor/editor_file_system.h" +#endif +#endif + void SpineAnimationMix::_bind_methods() { ClassDB::bind_method(D_METHOD("set_from", "from"), &SpineAnimationMix::set_from); @@ -175,16 +191,113 @@ void SpineSkeletonDataResource::_bind_methods() { #endif ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animation_mixes"), "set_animation_mixes", "get_animation_mixes"); + +#ifdef TOOLS_ENABLED +#if VERSION_MAJOR > 3 + ClassDB::bind_method(D_METHOD("_on_resources_reimported", "resources"), + &SpineSkeletonDataResource::_on_resources_reimported); +#else + ClassDB::bind_method(D_METHOD("_on_resources_reimported", "resources"), + &SpineSkeletonDataResource::_on_resources_reimported); +#endif +#endif } +#ifdef TOOLS_ENABLED +EditorFileSystem *get_editor_file_system() { +#ifdef SPINE_GODOT_EXTENSION + EditorInterface *editor_interface = EditorInterface::get_singleton(); + if (editor_interface) { + return editor_interface->get_resource_filesystem(); + } + return nullptr; +#else + return EditorFileSystem::get_singleton(); +#endif +} +#endif + SpineSkeletonDataResource::SpineSkeletonDataResource() - : default_mix(0), skeleton_data(nullptr), animation_state_data(nullptr) {} + : default_mix(0), skeleton_data(nullptr), animation_state_data(nullptr) { + +#ifdef TOOLS_ENABLED +#if VERSION_MAJOR > 3 + if (Engine::get_singleton()->is_editor_hint()) { + EditorFileSystem *efs = get_editor_file_system(); + if (efs) { + efs->connect("resources_reimported", callable_mp(this, &SpineSkeletonDataResource::_on_resources_reimported)); + } + } +#else + if (Engine::get_singleton()->is_editor_hint()) { + EditorFileSystem *efs = EditorFileSystem::get_singleton(); + if (efs) { + efs->connect("resources_reimported", this, "_on_resources_reimported"); + } + } +#endif +#endif +} SpineSkeletonDataResource::~SpineSkeletonDataResource() { +#ifdef TOOLS_ENABLED +#if VERSION_MAJOR > 3 + if (Engine::get_singleton()->is_editor_hint()) { + EditorFileSystem *efs = get_editor_file_system(); + if (efs && efs->is_connected("resources_reimported", callable_mp(this, &SpineSkeletonDataResource::_on_resources_reimported))) { + efs->disconnect("resources_reimported", callable_mp(this, &SpineSkeletonDataResource::_on_resources_reimported)); + } + } +#else + if (Engine::get_singleton()->is_editor_hint()) { + EditorFileSystem *efs = EditorFileSystem::get_singleton(); + if (efs && efs->is_connected("resources_reimported", this, "_on_resources_reimported")) { + efs->disconnect("resources_reimported", this, "_on_resources_reimported"); + } + } +#endif +#endif + delete skeleton_data; delete animation_state_data; } +#ifdef TOOLS_ENABLED +#if VERSION_MAJOR > 3 +void SpineSkeletonDataResource::_on_resources_reimported(const PackedStringArray &resources) { + for (int i = 0; i < resources.size(); i++) { + if (atlas_res.is_valid() && atlas_res->get_path() == resources[i]) { +#ifdef SPINE_GODOT_EXTENSION + atlas_res = ResourceLoader::get_singleton()->load(resources[i], "SpineAtlasResource", ResourceLoader::CACHE_MODE_IGNORE); +#else + atlas_res = ResourceLoader::load(resources[i], "SpineAtlasResource", ResourceFormatLoader::CACHE_MODE_IGNORE); +#endif + update_skeleton_data(); + } else if (skeleton_file_res.is_valid() && skeleton_file_res->get_path() == resources[i]) { +#ifdef SPINE_GODOT_EXTENSION + skeleton_file_res = ResourceLoader::get_singleton()->load(resources[i], "SpineSkeletonFileResource", ResourceLoader::CACHE_MODE_IGNORE); +#else + skeleton_file_res = ResourceLoader::load(resources[i], "SpineSkeletonFileResource", ResourceFormatLoader::CACHE_MODE_IGNORE); +#endif + update_skeleton_data(); + } + } +} +#else +void SpineSkeletonDataResource::_on_resources_reimported(const PoolStringArray &resources) { + for (int i = 0; i < resources.size(); i++) { + if (atlas_res.is_valid() && atlas_res->get_path() == resources[i]) { + atlas_res = ResourceLoader::load(resources[i]); + update_skeleton_data(); + } else if (skeleton_file_res.is_valid() && skeleton_file_res->get_path() == resources[i]) { + skeleton_file_res = ResourceLoader::load(resources[i]); + update_skeleton_data(); + } + } +} +#endif +#endif + void SpineSkeletonDataResource::update_skeleton_data() { if (skeleton_data) { delete skeleton_data; @@ -249,22 +362,6 @@ bool SpineSkeletonDataResource::is_skeleton_data_loaded() const { void SpineSkeletonDataResource::set_atlas_res( const Ref &atlas) { atlas_res = atlas; - if (atlas_res.is_valid()) { -#if VERSION_MAJOR > 3 - if (!atlas_res->is_connected( - SNAME("skeleton_atlas_changed"), - callable_mp(this, - &SpineSkeletonDataResource::update_skeleton_data))) - atlas_res->connect( - SNAME("skeleton_atlas_changed"), - callable_mp(this, &SpineSkeletonDataResource::update_skeleton_data)); -#else - if (!atlas_res->is_connected(SNAME("skeleton_atlas_changed"), this, - SNAME("update_skeleton_data"))) - atlas_res->connect(SNAME("skeleton_atlas_changed"), this, - SNAME("update_skeleton_data")); -#endif - } update_skeleton_data(); } @@ -275,22 +372,6 @@ Ref SpineSkeletonDataResource::get_atlas_res() { void SpineSkeletonDataResource::set_skeleton_file_res( const Ref &skeleton_file) { skeleton_file_res = skeleton_file; - if (skeleton_file_res.is_valid()) { -#if VERSION_MAJOR > 3 - if (!skeleton_file_res->is_connected( - SNAME("skeleton_file_changed"), - callable_mp(this, - &SpineSkeletonDataResource::update_skeleton_data))) - skeleton_file_res->connect( - SNAME("skeleton_file_changed"), - callable_mp(this, &SpineSkeletonDataResource::update_skeleton_data)); -#else - if (!skeleton_file_res->is_connected(SNAME("skeleton_file_changed"), this, - SNAME("update_skeleton_data"))) - skeleton_file_res->connect(SNAME("skeleton_file_changed"), this, - SNAME("update_skeleton_data")); -#endif - } update_skeleton_data(); } diff --git a/spine-godot/spine_godot/SpineSkeletonDataResource.h b/spine-godot/spine_godot/SpineSkeletonDataResource.h index 28f542fd0..d0cbc9365 100644 --- a/spine-godot/spine_godot/SpineSkeletonDataResource.h +++ b/spine-godot/spine_godot/SpineSkeletonDataResource.h @@ -209,4 +209,12 @@ public: float get_reference_scale() const; void set_reference_scale(float reference_scale); + +#ifdef TOOLS_ENABLED +#if VERSION_MAJOR > 3 + void _on_resources_reimported(const PackedStringArray &resources); +#else + void _on_resources_reimported(const PoolStringArray &resources); +#endif +#endif }; diff --git a/spine-godot/spine_godot/SpineSkeletonFileResource.cpp b/spine-godot/spine_godot/SpineSkeletonFileResource.cpp index 93d13fba2..b5404fc59 100644 --- a/spine-godot/spine_godot/SpineSkeletonFileResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonFileResource.cpp @@ -95,7 +95,6 @@ static char *readString(BinaryInput *input) { void SpineSkeletonFileResource::_bind_methods() { ClassDB::bind_method(D_METHOD("load_from_file", "path"), &SpineSkeletonFileResource::load_from_file); - ADD_SIGNAL(MethodInfo("skeleton_file_changed")); } static bool checkVersion(const char *version) { diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index 7427f7199..ecf844c9a 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -1216,8 +1216,9 @@ void SpineSprite::draw() { } #if TOOLS_ENABLED + float editor_scale = 1.0; + if (Engine::get_singleton()->is_editor_hint()) editor_scale = EditorInterface::get_singleton()->get_editor_scale(); - float editor_scale = EditorInterface::get_singleton()->get_editor_scale(); float inverse_zoom = 1 / get_viewport()->get_global_canvas_transform().get_scale().x * editor_scale; Vector hover_text_lines; if (hovered_slot) { diff --git a/spine-godot/spine_godot_extension.dev.gdextension b/spine-godot/spine_godot_extension.dev.gdextension deleted file mode 100644 index d4d2d8495..000000000 --- a/spine-godot/spine_godot_extension.dev.gdextension +++ /dev/null @@ -1,18 +0,0 @@ -[configuration] - -entry_symbol = "spine_godot_library_init" -compatibility_minimum = "4.1" - -[libraries] - -macos.editor = "res://bin/macos/macos.framework/libspine_godot.macos.dev.editor" -macos.debug = "res://bin/macos/macos.framework/libspine_godot.macos.dev.template_debug" -macos.release = "res://bin/macos/macos.framework/libspine_godot.macos.template_release" - -windows.editor.x86_64 = "res://bin/windows/libspine_godot.windows.editor.dev.x86_64.dll" -windows.debug.x86_64 = "res://bin/windows/libspine_godot.windows.template_debug.dev.x86_64.dll" -windows.release.x86_64 = "res://bin/windows/libspine_godot.windows.template_release.dev.x86_64.dll" - -linux.editor.x86_64 = "res://bin/linux/libspine_godot.linux.editor.dev.x86_64.so" -linux.debug.x86_64 = "res://bin/linux/libspine_godot.linux.template_debug.dev.x86_64.so" -linux.release.x86_64 = "res://bin/linux/libspine_godot.linux.template_release.dev.x86_64.so" \ No newline at end of file diff --git a/spine-haxe/README.md b/spine-haxe/README.md index 5050b84dc..d63875ff6 100644 --- a/spine-haxe/README.md +++ b/spine-haxe/README.md @@ -23,12 +23,17 @@ spine-haxe works with data exported from Spine 4.2.xx. spine-haxe supports all Spine features except premultiplied alpha atlases and two color tinting. ## Setup -The core module of spine-haxe has zero dependencies. The rendering implementation through Starling has two dependencies: openfl and starling. +The spine-haxe runtime is composed of a core module, that is a Haxe implementation of the renderer-agnostic Spine Runtimes core APIs, and the following specific renderer implementations: + - [Starling](https://lib.haxe.org/p/starling/) + - [HaxeFlixel](https://lib.haxe.org/p/flixel/) (minimum supported version 5.9.0) + +The core module of spine-haxe has zero dependencies. The rendering implementation depends on: openfl, starling, and flixel. To use spine-haxe you have first to install all the necessary dependencies: ``` haxelib install openfl haxelib install starling +haxelib install flixel ``` Once you have installed the dependencies, you can [download the latest version of spine-haxe](https://esotericsoftware.com/files/spine-haxe/4.2/spine-haxe-latest.zip) and install it: @@ -60,6 +65,7 @@ To setup the development environment install the following: haxelib install openfl haxelib run openfl setup haxelib install starling + haxelib install flixel ``` 3. Clone the `spine-runtimes` repository, and use `haxelib` to setup a dev library: ``` diff --git a/spine-haxe/example/src/Main.hx b/spine-haxe/example/src/Main.hx index 63712f6ab..72fa2cc40 100644 --- a/spine-haxe/example/src/Main.hx +++ b/spine-haxe/example/src/Main.hx @@ -27,24 +27,145 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; -import openfl.display.Sprite; -import openfl.geom.Rectangle; +package; + +import flixelExamples.FlixelState; +import starlingExamples.BasicExample; +import starlingExamples.Scene.SceneManager; import starling.core.Starling; +import flixel.FlxG; +import flixel.FlxGame; + +import openfl.display.Sprite; +import openfl.text.TextField; +import openfl.text.TextFormat; +import openfl.events.MouseEvent; + +import openfl.geom.Rectangle; import starling.events.Event; class Main extends Sprite { + private var background:Sprite; + private var flixelButton:Sprite; + private var starlingButton:Sprite; + private var uiContainer:Sprite; + + private static inline var ratio = 4; + private static inline var STAGE_WIDTH:Int = 100 * ratio; + private static inline var STAGE_HEIGHT:Int = 200 * ratio; + private static inline var BUTTON_WIDTH:Int = 80 * ratio; + private static inline var BUTTON_HEIGHT:Int = 40 * ratio; + private static inline var BUTTON_SPACING:Int = 20 * ratio; + + public function new() { + super(); + addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); + } + + private function onAddedToStage(e:Event):Void { + removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); + createUI(); + centerUI(); + stage.addEventListener(Event.RESIZE, onResize); + } + + private function createUI():Void { + uiContainer = new Sprite(); + addChild(uiContainer); + + background = new Sprite(); + background.graphics.beginFill(0xA2A2A2); + background.graphics.drawRect(0, 0, STAGE_WIDTH, STAGE_HEIGHT); + background.graphics.endFill(); + uiContainer.addChild(background); + + flixelButton = createButton("Flixel", 0xFF0000); + uiContainer.addChild(flixelButton); + + starlingButton = createButton("Starling", 0x00FF00); + uiContainer.addChild(starlingButton); + + positionButtons(); + + flixelButton.addEventListener(MouseEvent.CLICK, onFlixelClick); + starlingButton.addEventListener(MouseEvent.CLICK, onStarlingClick); + } + + private function createButton(label:String, color:Int):Sprite { + var button = new Sprite(); + var g = button.graphics; + + g.beginFill(color); + g.drawRoundRect(0, 0, BUTTON_WIDTH, BUTTON_HEIGHT, 10, 10); + g.endFill(); + + // Add button text + var tf = new TextField(); + var format = new TextFormat("_sans", 14 * ratio, 0x000000, true, null, null, null, null, "center"); + tf.defaultTextFormat = format; + tf.text = label; + tf.width = BUTTON_WIDTH; + tf.height = BUTTON_HEIGHT; + tf.mouseEnabled = false; + tf.selectable = false; + + tf.y = (BUTTON_HEIGHT - tf.textHeight) / 2; + + button.addChild(tf); + + return button; + } + + private function positionButtons():Void { + var totalHeight = (BUTTON_HEIGHT * 2) + BUTTON_SPACING; + var startY = (STAGE_HEIGHT - totalHeight) / 2; + + flixelButton.x = (STAGE_WIDTH - BUTTON_WIDTH) / 2; + flixelButton.y = startY + BUTTON_HEIGHT + BUTTON_SPACING; + + starlingButton.x = (STAGE_WIDTH - BUTTON_WIDTH) / 2; + starlingButton.y = startY; + } + + private function centerUI():Void { + uiContainer.x = (stage.stageWidth - STAGE_WIDTH) / 2; + uiContainer.y = (stage.stageHeight - STAGE_HEIGHT) / 2; + } + + private function onResize(e:Event):Void { + centerUI(); + } + + private function onFlixelClick(e:MouseEvent):Void { + trace("Launching Flixel game"); + destroyUI(); + addChild(new FlxGame(640, 480, FlixelState)); + FlxG.autoPause = false; + } + + private function destroyUI():Void { + flixelButton.removeEventListener(MouseEvent.CLICK, onFlixelClick); + starlingButton.removeEventListener(MouseEvent.CLICK, onStarlingClick); + stage.removeEventListener(Event.RESIZE, onResize); + + removeChild(uiContainer); + + background = null; + flixelButton = null; + starlingButton = null; + uiContainer = null; + } + private var starlingSingleton:Starling; - - public function new() { - super(); - + private function onStarlingClick(e:MouseEvent):Void { + trace("Launching Starling game"); starlingSingleton = new Starling(starling.display.Sprite, stage, new Rectangle(0, 0, 800, 600)); starlingSingleton.supportHighResolutions = true; starlingSingleton.addEventListener(Event.ROOT_CREATED, onStarlingRootCreated); - } + } private function onStarlingRootCreated(event:Event):Void { + destroyUI(); starlingSingleton.removeEventListener(Event.ROOT_CREATED, onStarlingRootCreated); starlingSingleton.start(); Starling.current.stage.color = 0x000000; diff --git a/spine-haxe/example/src/MainFlixel.hx b/spine-haxe/example/src/MainFlixel.hx new file mode 100644 index 000000000..4c7334041 --- /dev/null +++ b/spine-haxe/example/src/MainFlixel.hx @@ -0,0 +1,45 @@ +/****************************************************************************** + * 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; + +import flixelExamples.FlixelState; +import flixel.FlxG; +import flixel.FlxGame; +import openfl.display.Sprite; + +class MainFlixel extends Sprite +{ + public function new() + { + super(); + addChild(new FlxGame(640, 480, FlixelState)); + FlxG.autoPause = false; + } +} diff --git a/spine-haxe/example/src/MainStarling.hx b/spine-haxe/example/src/MainStarling.hx new file mode 100644 index 000000000..f5dfb3636 --- /dev/null +++ b/spine-haxe/example/src/MainStarling.hx @@ -0,0 +1,57 @@ +/****************************************************************************** + * 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; + +import starlingExamples.BasicExample; +import starlingExamples.Scene.SceneManager; +import openfl.display.Sprite; +import openfl.geom.Rectangle; +import starling.core.Starling; +import starling.events.Event; + +class MainStarling extends Sprite { + private var starlingSingleton:Starling; + + public function new() { + super(); + + starlingSingleton = new Starling(starling.display.Sprite, stage, new Rectangle(0, 0, 800, 600)); + starlingSingleton.supportHighResolutions = true; + starlingSingleton.addEventListener(Event.ROOT_CREATED, onStarlingRootCreated); + } + + private function onStarlingRootCreated(event:Event):Void { + starlingSingleton.removeEventListener(Event.ROOT_CREATED, onStarlingRootCreated); + starlingSingleton.start(); + Starling.current.stage.color = 0x000000; + + SceneManager.getInstance().switchScene(new BasicExample()); + } +} diff --git a/spine-haxe/example/src/flixelExamples/AnimationBoundExample.hx b/spine-haxe/example/src/flixelExamples/AnimationBoundExample.hx new file mode 100644 index 000000000..fd15d54ad --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/AnimationBoundExample.hx @@ -0,0 +1,77 @@ +package flixelExamples; + + +import flixel.util.FlxColor; +import flixel.text.FlxText; +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class AnimationBoundExample extends FlxState { + var loadBinary = true; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> { + FlxG.debugger.drawDebug = false; + FlxG.switchState(() -> new ControlBonesExample()); + }); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/spineboy.atlas"), new FlixelTextureLoader("assets/spineboy.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/spineboy-pro.skel") : Assets.getText("assets/spineboy-pro.json"), atlas, .2); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSpriteClipping = new SkeletonSprite(data, animationStateData); + var animationClipping = skeletonSpriteClipping.state.setAnimationByName(0, "portal", true).animation; + skeletonSpriteClipping.update(0); + skeletonSpriteClipping.setBoundingBox(animationClipping, true); + skeletonSpriteClipping.screenCenter(); + skeletonSpriteClipping.x = FlxG.width / 4 - skeletonSpriteClipping.width / 2; + add(skeletonSpriteClipping); + var textClipping = new FlxText(); + textClipping.text = "Animation bound with clipping"; + textClipping.size = 12; + textClipping.x = skeletonSpriteClipping.x + skeletonSpriteClipping.width / 2 - textClipping.width / 2; + textClipping.y = skeletonSpriteClipping.y + skeletonSpriteClipping.height + 20; + textClipping.setBorderStyle(FlxTextBorderStyle.OUTLINE, FlxColor.RED, 2); + add(textClipping); + + var skeletonSpriteNoClipping = new SkeletonSprite(data, animationStateData); + var animationClipping = skeletonSpriteNoClipping.state.setAnimationByName(0, "portal", true).animation; + skeletonSpriteNoClipping.update(0); + skeletonSpriteNoClipping.setBoundingBox(animationClipping, false); + skeletonSpriteNoClipping.screenCenter(); + skeletonSpriteNoClipping.x = FlxG.width / 4 * 3 - skeletonSpriteClipping.width / 2 - 50; + add(skeletonSpriteNoClipping); + var textNoClipping = new FlxText(); + textNoClipping.text = "Animation bound without clipping"; + textNoClipping.size = 12; + textNoClipping.x = skeletonSpriteNoClipping.x + skeletonSpriteNoClipping.width / 2 - textNoClipping.width / 2; + textNoClipping.y = skeletonSpriteNoClipping.y + skeletonSpriteNoClipping.height + 20; + textNoClipping.setBorderStyle(FlxTextBorderStyle.OUTLINE, FlxColor.RED, 2); + add(textNoClipping); + + var textInstruction = new FlxText(); + textInstruction.text = "Red rectangle is the animation bound"; + textInstruction.size = 12; + textInstruction.screenCenter(); + textInstruction.y = textNoClipping.y + 40; + textInstruction.setBorderStyle(FlxTextBorderStyle.OUTLINE, FlxColor.RED, 2); + add(textInstruction); + + FlxG.debugger.drawDebug = true; + + super.create(); + } +} diff --git a/spine-haxe/example/src/flixelExamples/BasicExample.hx b/spine-haxe/example/src/flixelExamples/BasicExample.hx new file mode 100644 index 000000000..86b53b9f9 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/BasicExample.hx @@ -0,0 +1,87 @@ +/****************************************************************************** + * 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 flixelExamples; + +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class BasicExample extends FlxState { + var loadBinary = true; + + var skeletonSprite:SkeletonSprite; + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new SequenceExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/raptor.atlas"), new FlixelTextureLoader("assets/raptor-pro.atlas")); + var skeletondata = SkeletonData.from(loadBinary ? Assets.getBytes("assets/raptor-pro.skel") : Assets.getText("assets/raptor-pro.json"), atlas, .25); + var animationStateData = new AnimationStateData(skeletondata); + animationStateData.defaultMix = 0.25; + + skeletonSprite = new SkeletonSprite(skeletondata, animationStateData); + var animation = skeletonSprite.state.setAnimationByName(0, "walk", true).animation; + skeletonSprite.setBoundingBox(animation); + skeletonSprite.screenCenter(); + add(skeletonSprite); + + super.create(); + + trace("loaded"); + } + + override public function update(elapsed:Float):Void + { + if (FlxG.keys.anyPressed([RIGHT])) { + skeletonSprite.x += 15; + } + if (FlxG.keys.anyPressed([LEFT])) { + skeletonSprite.x -= 15; + } + if (FlxG.keys.anyPressed([DOWN])) { + skeletonSprite.y += 15; + } + if (FlxG.keys.anyPressed([UP])) { + skeletonSprite.y -= 15; + } + + super.update(elapsed); + } + +} diff --git a/spine-haxe/example/src/flixelExamples/CelestialCircusExample.hx b/spine-haxe/example/src/flixelExamples/CelestialCircusExample.hx new file mode 100644 index 000000000..5896ec541 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/CelestialCircusExample.hx @@ -0,0 +1,75 @@ +package flixelExamples; + + +import flixel.text.FlxText; +import flixel.math.FlxPoint; +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class CelestialCircusExample extends FlxState { + var loadBinary = true; + + var skeletonSprite:SkeletonSprite; + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new SnowglobeExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/celestial-circus.atlas"), new FlixelTextureLoader("assets/celestial-circus.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/celestial-circus-pro.skel") : Assets.getText("assets/celestial-circus-pro.json"), atlas, .15); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + skeletonSprite = new SkeletonSprite(data, animationStateData); + skeletonSprite.screenCenter(); + skeletonSprite.state.setAnimationByName(0, "eyeblink-long", true); + add(skeletonSprite); + + add(new FlxText(50, 50, 200, "Drag Celeste to move her around", 16)); + + super.create(); + } + + var mousePosition = FlxPoint.get(); + var dragging:Bool = false; + var lastX:Float = 0; + var lastY:Float = 0; + override public function update(elapsed:Float):Void + { + super.update(elapsed); + + mousePosition = FlxG.mouse.getPosition(); + + if (FlxG.mouse.justPressed && skeletonSprite.overlapsPoint(mousePosition)) + { + dragging = true; + lastX = mousePosition.x; + lastY = mousePosition.y; + } + + if (FlxG.mouse.justReleased) dragging = false; + + if (dragging) + { + skeletonSprite.x += mousePosition.x - lastX; + skeletonSprite.y += mousePosition.y - lastY; + skeletonSprite.skeleton.physicsTranslate( + mousePosition.x - lastX, + mousePosition.y - lastY, + ); + lastX = mousePosition.x; + lastY = mousePosition.y; + } + + } +} diff --git a/spine-haxe/example/src/flixelExamples/CloudPotExample.hx b/spine-haxe/example/src/flixelExamples/CloudPotExample.hx new file mode 100644 index 000000000..7a701cd84 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/CloudPotExample.hx @@ -0,0 +1,37 @@ +package flixelExamples; + + +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class CloudPotExample extends FlxState { + var loadBinary = true; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new AnimationBoundExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/cloud-pot.atlas"), new FlixelTextureLoader("assets/cloud-pot.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/cloud-pot.skel") : Assets.getText("assets/cloud-pot.json"), atlas, .25); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + skeletonSprite.screenCenter(); + skeletonSprite.state.setAnimationByName(0, "playing-in-the-rain", true); + add(skeletonSprite); + + super.create(); + } +} diff --git a/spine-haxe/example/src/flixelExamples/ControlBonesExample.hx b/spine-haxe/example/src/flixelExamples/ControlBonesExample.hx new file mode 100644 index 000000000..75b4cadf2 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/ControlBonesExample.hx @@ -0,0 +1,108 @@ +package flixelExamples; + + +import flixel.util.FlxSave; +import flixel.math.FlxPoint; +import flixel.util.FlxColor; +import flixel.util.FlxSpriteUtil; +import flixel.FlxSprite; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class ControlBonesExample extends FlxState { + var loadBinary = true; + + private var controlBones = []; + private var controls:Array = []; + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new EventsExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/stretchyman.atlas"), new FlixelTextureLoader("assets/stretchyman.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/stretchyman-pro.skel") : Assets.getText("assets/stretchyman-pro.json"), atlas); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + skeletonSprite.scaleX = .5; + skeletonSprite.scaleY = .5; + var animation = skeletonSprite.state.setAnimationByName(0, "idle", true).animation; + skeletonSprite.setBoundingBox(animation); + skeletonSprite.screenCenter(); + add(skeletonSprite); + + var controlBoneNames = [ + "back-arm-ik-target", + "back-leg-ik-target", + "front-arm-ik-target", + "front-leg-ik-target", + ]; + + var radius = 6; + for (boneName in controlBoneNames) { + var bone = skeletonSprite.skeleton.findBone(boneName); + var point = [bone.worldX, bone.worldY]; + skeletonSprite.skeletonToHaxeWorldCoordinates(point); + var control = new FlxSprite(); + control.makeGraphic(radius * 2, radius * 2, FlxColor.TRANSPARENT, true); + FlxSpriteUtil.drawCircle(control, radius, radius, radius, 0xffff00ff); + control.setPosition(point[0] - radius, point[1] - radius); + controlBones.push(bone); + controls.push(control); + add(control); + } + + var point = [.0, .0]; + skeletonSprite.beforeUpdateWorldTransforms = function (go) { + for (i in 0...controls.length) { + var bone = controlBones[i]; + var control = controls[i]; + point[0] = control.x + radius; + point[1] = control.y + radius; + go.haxeWorldCoordinatesToBone(point, bone); + bone.x = point[0]; + bone.y = point[1]; + } + }; + + super.create(); + } + + var mousePosition = FlxPoint.get(); + var offsetX:Float = 0; + var offsetY:Float = 0; + var sprite:FlxSprite; + override public function update(elapsed:Float):Void + { + super.update(elapsed); + + mousePosition = FlxG.mouse.getPosition(); + + for (control in controls) { + if (FlxG.mouse.justPressed && control.overlapsPoint(mousePosition)) + { + sprite = control; + offsetX = mousePosition.x - sprite.x; + offsetY = mousePosition.y - sprite.y; + } + } + + if (FlxG.mouse.justReleased) sprite = null; + + if (sprite != null) + { + sprite.x = mousePosition.x - offsetX; + sprite.y = mousePosition.y - offsetY; + } + } +} diff --git a/spine-haxe/example/src/flixelExamples/EventsExample.hx b/spine-haxe/example/src/flixelExamples/EventsExample.hx new file mode 100644 index 000000000..505902e26 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/EventsExample.hx @@ -0,0 +1,77 @@ +package flixelExamples; + + +import flixel.text.FlxText; +import flixel.ui.FlxButton; +import flixel.FlxG; +import flixel.group.FlxSpriteGroup; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class EventsExample extends FlxState { + var loadBinary = true; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new FlixelState())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/spineboy.atlas"), new FlixelTextureLoader("assets/spineboy.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/spineboy-pro.skel") : Assets.getText("assets/spineboy-pro.json"), atlas, .25); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + + // add callback to the AnimationState + skeletonSprite.state.onStart.add(entry -> log('Started animation ${entry.animation.name}')); + skeletonSprite.state.onInterrupt.add(entry -> log('Interrupted animation ${entry.animation.name}')); + skeletonSprite.state.onEnd.add(entry -> log('Ended animation ${entry.animation.name}')); + skeletonSprite.state.onDispose.add(entry -> log('Disposed animation ${entry.animation.name}')); + skeletonSprite.state.onComplete.add(entry -> log('Completed animation ${entry.animation.name}')); + + skeletonSprite.state.setAnimationByName(0, "walk", true); + + var trackEntry = skeletonSprite.state.addAnimationByName(0, "run", true, 3); + skeletonSprite.setBoundingBox(trackEntry.animation); + + skeletonSprite.setBoundingBox(); + skeletonSprite.screenCenter(); + skeletonSprite.skeleton.setBonesToSetupPose(); + add(skeletonSprite); + + trackEntry.onEvent.add( + (entry, event) -> log('Custom event for ${entry.animation.name}: ${event.data.name}')); + + + add(textContainer); + super.create(); + } + + private var textContainer = new FlxSpriteGroup(); + private var logs = new Array(); + private var logsNumber = 0; + private var yOffset = 12; + private function log(text:String) { + var length = logs.length; + var newLog = new FlxText(250, 30, text); + newLog.x = 50; + newLog.y = 20 + yOffset * logsNumber++; + newLog.color = 0xffffffff; + textContainer.add(newLog); + if (logs.length < 35) { + logs.push(newLog); + } else { + logs.shift().destroy(); + logs.push(newLog); + textContainer.y -= yOffset; + } + } +} diff --git a/spine-haxe/example/src/flixelExamples/FlixelState.hx b/spine-haxe/example/src/flixelExamples/FlixelState.hx new file mode 100644 index 000000000..110f9b713 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/FlixelState.hx @@ -0,0 +1,195 @@ +package flixelExamples; + +import flixel.ui.FlxButton; +import flixel.group.FlxSpriteGroup; +import flixel.FlxSprite; +import flixel.graphics.FlxGraphic; +import spine.animation.AnimationStateData; +import openfl.Assets; +import spine.atlas.TextureAtlas; +import spine.SkeletonData; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxG; +import flixel.FlxState; +import flixel.text.FlxText; + +class FlixelState extends FlxState +{ + var spineSprite:SkeletonSprite; + var sprite:FlxSprite; + var sprite2:FlxSprite; + var myText:FlxText; + var group:FlxSpriteGroup; + var justSetWalking = false; + + var jumping = false; + + var scale = 4; + var speed:Float; + + override public function create():Void + { + FlxG.cameras.bgColor = 0xffa1b2b0; + + // setting speed of spineboy (450 is the speed to not let him slide) + speed = 450 / scale; + + // creating a group + group = new FlxSpriteGroup(); + group.setPosition(50, 50); + add(group); + + // creating the sprite to check overlapping + sprite = new FlxSprite(); + sprite.loadGraphic(FlxGraphic.fromRectangle(150, 100, 0xff8d008d)); + group.add(sprite); + + // creating the text to display overlapping state + myText = new FlxText(0, 25, 150, "", 16); + myText.alignment = CENTER; + group.add(myText); + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new BasicExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + // creating a sprite for the floor + var floor = new FlxSprite(); + floor.loadGraphic(FlxGraphic.fromRectangle(FlxG.width, FlxG.height - 100, 0xff822f02)); + floor.y = FlxG.height - 100; + add(floor); + + // instructions + var groupInstructions = new FlxSpriteGroup(); + groupInstructions.setPosition(50, 405); + groupInstructions.add(new FlxText(0, 0, 200, "Left/Right - Move", 16)); + groupInstructions.add(new FlxText(0, 25, 150, "Space - Jump", 16)); + groupInstructions.add(new FlxText(200, 25, 400, "Click the button for the next example", 16)); + add(groupInstructions); + + // loading spineboy + var atlas = new TextureAtlas(Assets.getText("assets/spineboy.atlas"), new FlixelTextureLoader("assets/spineboy.atlas")); + var skeletondata = SkeletonData.from(Assets.getText("assets/spineboy-pro.json"), atlas, 1/scale); + var animationStateData = new AnimationStateData(skeletondata); + spineSprite = new SkeletonSprite(skeletondata, animationStateData); + + // positioning spineboy + spineSprite.setPosition(.5 * FlxG.width, .5 * FlxG.height); + + // setting mix times + animationStateData.defaultMix = 0.5; + animationStateData.setMixByName("idle", "walk", 0.1); + animationStateData.setMixByName("walk", "idle", 0.1); + animationStateData.setMixByName("idle", "idle-turn", 0.05); + animationStateData.setMixByName("idle-turn", "idle", 0.05); + animationStateData.setMixByName("idle-turn", "walk", 0.3); + animationStateData.setMixByName("idle", "jump", 0); + animationStateData.setMixByName("jump", "idle", 0.05); + animationStateData.setMixByName("jump", "walk", 0.05); + animationStateData.setMixByName("walk", "jump", 0.05); + + // setting idle animation + spineSprite.state.setAnimationByName(0, "idle", true); + + // setting y offset function to move object body while jumping + var hip = spineSprite.skeleton.findBone("hip"); + var initialY = 0.; + var initialOffsetY = 0.; + spineSprite.state.onStart.add(entry -> { + if (entry.animation.name == "jump") { + initialY = spineSprite.y; + initialOffsetY = spineSprite.offsetY; + } + }); + spineSprite.state.onComplete.add(entry -> { + if (entry.animation.name == "jump") { + jumping = false; + spineSprite.y = initialY; + spineSprite.offsetY = initialOffsetY; + } + }); + var diff = .0; + spineSprite.afterUpdateWorldTransforms = spineSprite -> { + if (jumping) { + diff -= hip.y; + spineSprite.offsetY -= diff; + spineSprite.y += diff; + } + diff = hip.y; + } + + // adding spineboy to the stage + add(spineSprite); + + // FlxG.debugger.visible = !FlxG.debugger.visible; + // debug ui + // FlxG.debugger.visible = true; + // FlxG.debugger.drawDebug = true; + // FlxG.log.redirectTraces = true; + + // FlxG.debugger.track(spineSprite); + // FlxG.watch.add(spineSprite, "width"); + // FlxG.watch.add(spineSprite, "offsetY"); + // FlxG.watch.add(spineSprite, "y"); + // FlxG.watch.add(this, "jumping"); + super.create(); + } + + var justSetIdle = true; + override public function update(elapsed:Float):Void + { + if (FlxG.overlap(spineSprite, group)) { + myText.text = "Overlapping"; + } else { + myText.text = "Non overlapping"; + } + + if (!jumping && FlxG.keys.anyJustPressed([SPACE])) { + spineSprite.state.setAnimationByName(0, "jump", false); + jumping = true; + justSetIdle = false; + justSetWalking = false; + } + + if (FlxG.keys.anyJustPressed([J])) { + // spineSprite.antialiasing = !spineSprite.antialiasing; + FlxG.debugger.visible = !FlxG.debugger.visible; + } + + if (FlxG.keys.anyPressed([RIGHT, LEFT])) { + justSetIdle = false; + var flipped = false; + var deltaX; + if (FlxG.keys.anyPressed([RIGHT])) { + if (spineSprite.flipX == true) flipped = true; + spineSprite.flipX = false; + } + if (FlxG.keys.anyPressed([LEFT])) { + if (spineSprite.flipX == false) flipped = true; + spineSprite.flipX = true; + } + + deltaX = (spineSprite.flipX == false ? 1 : -1) * speed * elapsed; + spineSprite.x += deltaX; + + if (!jumping && !justSetWalking) { + justSetWalking = true; + if (flipped) { + spineSprite.state.setAnimationByName(0, "idle-turn", false); + spineSprite.state.addAnimationByName(0, "walk", true, 0); + } else { + spineSprite.state.setAnimationByName(0, "walk", true); + } + } + + } else if (!jumping && !justSetIdle) { + justSetWalking = false; + justSetIdle = true; + spineSprite.state.setAnimationByName(0, "idle", true); + } + + + super.update(elapsed); + } +} \ No newline at end of file diff --git a/spine-haxe/example/src/flixelExamples/MixAndMatchExample.hx b/spine-haxe/example/src/flixelExamples/MixAndMatchExample.hx new file mode 100644 index 000000000..f179f137a --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/MixAndMatchExample.hx @@ -0,0 +1,55 @@ +package flixelExamples; + + +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class MixAndMatchExample extends FlxState { + var loadBinary = false; + // var loadBinary = true; + + var skeletonSprite:SkeletonSprite; + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new TankExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/mix-and-match.atlas"), new FlixelTextureLoader("assets/mix-and-match.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/mix-and-match-pro.skel") : Assets.getText("assets/mix-and-match-pro.json"), atlas, .5); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + skeletonSprite = new SkeletonSprite(data, animationStateData); + var customSkin = new Skin("custom"); + var skinBase = data.findSkin("skin-base"); + customSkin.addSkin(skinBase); + customSkin.addSkin(data.findSkin("nose/short")); + customSkin.addSkin(data.findSkin("eyelids/girly")); + customSkin.addSkin(data.findSkin("eyes/violet")); + customSkin.addSkin(data.findSkin("hair/brown")); + customSkin.addSkin(data.findSkin("clothes/hoodie-orange")); + customSkin.addSkin(data.findSkin("legs/pants-jeans")); + customSkin.addSkin(data.findSkin("accessories/bag")); + customSkin.addSkin(data.findSkin("accessories/hat-red-yellow")); + skeletonSprite.skeleton.skin = customSkin; + + skeletonSprite.state.update(0); + var animation = skeletonSprite.state.setAnimationByName(0, "dance", true).animation; + skeletonSprite.setBoundingBox(animation); + skeletonSprite.screenCenter(); + add(skeletonSprite); + + super.create(); + } + +} diff --git a/spine-haxe/example/src/flixelExamples/SackExample.hx b/spine-haxe/example/src/flixelExamples/SackExample.hx new file mode 100644 index 000000000..beb8a965c --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/SackExample.hx @@ -0,0 +1,38 @@ +package flixelExamples; + + +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class SackExample extends FlxState { + var loadBinary = false; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new CelestialCircusExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/sack.atlas"), new FlixelTextureLoader("assets/sack.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/sack-pro.skel") : Assets.getText("assets/sack-pro.json"), atlas, .25); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + skeletonSprite.screenCenter(); + skeletonSprite.x -= 100; + skeletonSprite.state.setAnimationByName(0, "cape-follow-example", true); + add(skeletonSprite); + + super.create(); + } +} diff --git a/spine-haxe/example/src/flixelExamples/SequenceExample.hx b/spine-haxe/example/src/flixelExamples/SequenceExample.hx new file mode 100644 index 000000000..219a82086 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/SequenceExample.hx @@ -0,0 +1,39 @@ +package flixelExamples; + + +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class SequenceExample extends FlxState { + var loadBinary = true; + + var skeletonSprite:SkeletonSprite; + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new MixAndMatchExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/dragon.atlas"), new FlixelTextureLoader("assets/dragon.atlas")); + var skeletondata = SkeletonData.from(loadBinary ? Assets.getBytes("assets/dragon-ess.skel") : Assets.getText("assets/dragon-.json"), atlas, .5); + var animationStateData = new AnimationStateData(skeletondata); + animationStateData.defaultMix = 0.25; + + skeletonSprite = new SkeletonSprite(skeletondata, animationStateData); + + var animation = skeletonSprite.state.setAnimationByName(0, "flying", true).animation; + skeletonSprite.setBoundingBox(animation); + skeletonSprite.screenCenter(); + add(skeletonSprite); + super.create(); + } + +} diff --git a/spine-haxe/example/src/flixelExamples/SnowglobeExample.hx b/spine-haxe/example/src/flixelExamples/SnowglobeExample.hx new file mode 100644 index 000000000..40b7343e0 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/SnowglobeExample.hx @@ -0,0 +1,37 @@ +package flixelExamples; + + +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class SnowglobeExample extends FlxState { + var loadBinary = false; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new CloudPotExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/snowglobe.atlas"), new FlixelTextureLoader("assets/snowglobe.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/snowglobe-pro.skel") : Assets.getText("assets/snowglobe-pro.json"), atlas, .125); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + skeletonSprite.screenCenter(); + skeletonSprite.state.setAnimationByName(0, "shake", true); + add(skeletonSprite); + + super.create(); + } +} diff --git a/spine-haxe/example/src/flixelExamples/TankExample.hx b/spine-haxe/example/src/flixelExamples/TankExample.hx new file mode 100644 index 000000000..42a7563b2 --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/TankExample.hx @@ -0,0 +1,38 @@ +package flixelExamples; + + +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class TankExample extends FlxState { + var loadBinary = true; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new VineExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/tank.atlas"), new FlixelTextureLoader("assets/tank.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/tank-pro.skel") : Assets.getText("assets/tank-pro.json"), atlas, .125); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + var animation = skeletonSprite.state.setAnimationByName(0, "drive", true).animation; + skeletonSprite.setBoundingBox(animation); + skeletonSprite.screenCenter(); + add(skeletonSprite); + + super.create(); + } +} diff --git a/spine-haxe/example/src/flixelExamples/VineExample.hx b/spine-haxe/example/src/flixelExamples/VineExample.hx new file mode 100644 index 000000000..97d60bbfb --- /dev/null +++ b/spine-haxe/example/src/flixelExamples/VineExample.hx @@ -0,0 +1,38 @@ +package flixelExamples; + + +import spine.Skin; +import flixel.ui.FlxButton; +import flixel.FlxG; +import spine.flixel.SkeletonSprite; +import spine.flixel.FlixelTextureLoader; +import flixel.FlxState; +import openfl.utils.Assets; +import spine.SkeletonData; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlas; + +class VineExample extends FlxState { + var loadBinary = true; + + override public function create():Void { + FlxG.cameras.bgColor = 0xffa1b2b0; + + var button = new FlxButton(0, 0, "Next scene", () -> FlxG.switchState(() -> new SackExample())); + button.setPosition(FlxG.width * .75, FlxG.height / 10); + add(button); + + var atlas = new TextureAtlas(Assets.getText("assets/vine.atlas"), new FlixelTextureLoader("assets/vine.atlas")); + var data = SkeletonData.from(loadBinary ? Assets.getBytes("assets/vine-pro.skel") : Assets.getText("assets/vine-pro.json"), atlas, .4); + var animationStateData = new AnimationStateData(data); + animationStateData.defaultMix = 0.25; + + var skeletonSprite = new SkeletonSprite(data, animationStateData); + var animation = skeletonSprite.state.setAnimationByName(0, "grow", true).animation; + skeletonSprite.setBoundingBox(animation); + skeletonSprite.screenCenter(); + add(skeletonSprite); + + super.create(); + } +} diff --git a/spine-haxe/example/src/AnimationBoundExample.hx b/spine-haxe/example/src/starlingExamples/AnimationBoundExample.hx similarity index 97% rename from spine-haxe/example/src/AnimationBoundExample.hx rename to spine-haxe/example/src/starlingExamples/AnimationBoundExample.hx index 3a32c3975..3ef52b735 100644 --- a/spine-haxe/example/src/AnimationBoundExample.hx +++ b/spine-haxe/example/src/starlingExamples/AnimationBoundExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.Physics; @@ -56,17 +58,17 @@ class AnimationBoundExample extends Scene { skeletonSpriteClipping = new SkeletonSprite(skeletondata, animationStateDataClipping); skeletonSpriteClipping.skeleton.updateWorldTransform(Physics.update); - + skeletonSpriteClipping.scale = scale; skeletonSpriteClipping.x = Starling.current.stage.stageWidth / 3 * 2; skeletonSpriteClipping.y = Starling.current.stage.stageHeight / 2; - + var animationClipping = skeletonSpriteClipping.state.setAnimationByName(0, "portal", true).animation; var animationBoundClipping = skeletonSpriteClipping.getAnimationBounds(animationClipping, true); var quad:Quad = new Quad(animationBoundClipping.width * scale, animationBoundClipping.height * scale, 0xc70000); quad.x = skeletonSpriteClipping.x + animationBoundClipping.x * scale; quad.y = skeletonSpriteClipping.y + animationBoundClipping.y * scale; - + var animationStateDataNoClipping = new AnimationStateData(skeletondata); animationStateDataNoClipping.defaultMix = 0.25; skeletonSpriteNoClipping = new SkeletonSprite(skeletondata, animationStateDataNoClipping); @@ -83,7 +85,7 @@ class AnimationBoundExample extends Scene { addChild(quad); addChild(quadNoClipping); - addChild(skeletonSpriteClipping); + addChild(skeletonSpriteClipping); addChild(skeletonSpriteNoClipping); addText("Animation bound without clipping", 75, 350); addText("Animation bound with clipping", 370, 350); diff --git a/spine-haxe/example/src/BasicExample.hx b/spine-haxe/example/src/starlingExamples/BasicExample.hx similarity index 97% rename from spine-haxe/example/src/BasicExample.hx rename to spine-haxe/example/src/starlingExamples/BasicExample.hx index 67f53856e..4fbc298d7 100644 --- a/spine-haxe/example/src/BasicExample.hx +++ b/spine-haxe/example/src/starlingExamples/BasicExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; diff --git a/spine-haxe/example/src/CelestialCircusExample.hx b/spine-haxe/example/src/starlingExamples/CelestialCircusExample.hx similarity index 98% rename from spine-haxe/example/src/CelestialCircusExample.hx rename to spine-haxe/example/src/starlingExamples/CelestialCircusExample.hx index ece50e7fd..33a82dbbc 100644 --- a/spine-haxe/example/src/CelestialCircusExample.hx +++ b/spine-haxe/example/src/starlingExamples/CelestialCircusExample.hx @@ -27,8 +27,10 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +package starlingExamples; + import spine.BlendMode; -import Scene.SceneManager; +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.Physics; diff --git a/spine-haxe/example/src/CloudPotExample.hx b/spine-haxe/example/src/starlingExamples/CloudPotExample.hx similarity index 97% rename from spine-haxe/example/src/CloudPotExample.hx rename to spine-haxe/example/src/starlingExamples/CloudPotExample.hx index 3aa77c7c4..6c6bc3bf4 100644 --- a/spine-haxe/example/src/CloudPotExample.hx +++ b/spine-haxe/example/src/starlingExamples/CloudPotExample.hx @@ -27,8 +27,10 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +package starlingExamples; + import spine.BlendMode; -import Scene.SceneManager; +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.Physics; @@ -56,11 +58,11 @@ class CloudPotExample extends Scene { skeletonSprite.skeleton.updateWorldTransform(Physics.update); var bounds = skeletonSprite.skeleton.getBounds(); - + skeletonSprite.scale = 0.2; skeletonSprite.x = Starling.current.stage.stageWidth / 2; skeletonSprite.y = Starling.current.stage.stageHeight / 2; - + skeletonSprite.state.setAnimationByName(0, "playing-in-the-rain", true); addChild(skeletonSprite); diff --git a/spine-haxe/example/src/ControlBonesExample.hx b/spine-haxe/example/src/starlingExamples/ControlBonesExample.hx similarity index 98% rename from spine-haxe/example/src/ControlBonesExample.hx rename to spine-haxe/example/src/starlingExamples/ControlBonesExample.hx index 3ab20fca8..e171fe2ee 100644 --- a/spine-haxe/example/src/ControlBonesExample.hx +++ b/spine-haxe/example/src/starlingExamples/ControlBonesExample.hx @@ -27,8 +27,10 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +package starlingExamples; + import openfl.geom.Point; -import Scene.SceneManager; +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; @@ -42,7 +44,7 @@ import starling.display.Canvas; class ControlBonesExample extends Scene { var loadBinary = true; - + var skeletonSprite:SkeletonSprite; private var movement = new openfl.geom.Point(); private var controlBones = []; @@ -133,7 +135,7 @@ class ControlBonesExample extends Scene { skeletonSprite.skeleton.y += movement.y / skeletonSprite.scale; } } - + if (touchBackground) { var sceneTouch = e.getTouch(this); if (sceneTouch != null && sceneTouch.phase == TouchPhase.ENDED) { diff --git a/spine-haxe/example/src/EventsExample.hx b/spine-haxe/example/src/starlingExamples/EventsExample.hx similarity index 98% rename from spine-haxe/example/src/EventsExample.hx rename to spine-haxe/example/src/starlingExamples/EventsExample.hx index eb4e85a30..203f5cd6f 100644 --- a/spine-haxe/example/src/EventsExample.hx +++ b/spine-haxe/example/src/starlingExamples/EventsExample.hx @@ -27,8 +27,10 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +package starlingExamples; + import spine.animation.TrackEntry; -import Scene.SceneManager; +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; diff --git a/spine-haxe/example/src/MixAndMatchExample.hx b/spine-haxe/example/src/starlingExamples/MixAndMatchExample.hx similarity index 98% rename from spine-haxe/example/src/MixAndMatchExample.hx rename to spine-haxe/example/src/starlingExamples/MixAndMatchExample.hx index 198bead50..089ab4c09 100644 --- a/spine-haxe/example/src/MixAndMatchExample.hx +++ b/spine-haxe/example/src/starlingExamples/MixAndMatchExample.hx @@ -27,8 +27,10 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +package starlingExamples; + import spine.Skin; -import Scene.SceneManager; +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; diff --git a/spine-haxe/example/src/SackExample.hx b/spine-haxe/example/src/starlingExamples/SackExample.hx similarity index 97% rename from spine-haxe/example/src/SackExample.hx rename to spine-haxe/example/src/starlingExamples/SackExample.hx index 00c4daa6b..110b9be5e 100644 --- a/spine-haxe/example/src/SackExample.hx +++ b/spine-haxe/example/src/starlingExamples/SackExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.Physics; @@ -53,11 +55,11 @@ class SackExample extends Scene { var skeletonSprite = new SkeletonSprite(skeletondata, animationStateData); skeletonSprite.skeleton.updateWorldTransform(Physics.update); - + skeletonSprite.scale = 0.2; skeletonSprite.x = Starling.current.stage.stageWidth / 2; skeletonSprite.y = Starling.current.stage.stageHeight/ 2; - + skeletonSprite.state.setAnimationByName(0, "cape-follow-example", true); addChild(skeletonSprite); diff --git a/spine-haxe/example/src/Scene.hx b/spine-haxe/example/src/starlingExamples/Scene.hx similarity index 99% rename from spine-haxe/example/src/Scene.hx rename to spine-haxe/example/src/starlingExamples/Scene.hx index 801f8667f..e6f356abc 100644 --- a/spine-haxe/example/src/Scene.hx +++ b/spine-haxe/example/src/starlingExamples/Scene.hx @@ -27,6 +27,8 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +package starlingExamples; + import starling.display.Quad; import starling.text.TextField; import starling.core.Starling; diff --git a/spine-haxe/example/src/SequenceExample.hx b/spine-haxe/example/src/starlingExamples/SequenceExample.hx similarity index 97% rename from spine-haxe/example/src/SequenceExample.hx rename to spine-haxe/example/src/starlingExamples/SequenceExample.hx index 3eb20360b..f37c134fe 100644 --- a/spine-haxe/example/src/SequenceExample.hx +++ b/spine-haxe/example/src/starlingExamples/SequenceExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; diff --git a/spine-haxe/example/src/SnowglobeExample.hx b/spine-haxe/example/src/starlingExamples/SnowglobeExample.hx similarity index 97% rename from spine-haxe/example/src/SnowglobeExample.hx rename to spine-haxe/example/src/starlingExamples/SnowglobeExample.hx index f579c8f3f..1a7cc8369 100644 --- a/spine-haxe/example/src/SnowglobeExample.hx +++ b/spine-haxe/example/src/starlingExamples/SnowglobeExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.Physics; @@ -55,11 +57,11 @@ class SnowglobeExample extends Scene { skeletonSprite.skeleton.updateWorldTransform(Physics.update); var bounds = skeletonSprite.skeleton.getBounds(); - + skeletonSprite.scale = 0.15; skeletonSprite.x = Starling.current.stage.stageWidth / 2; skeletonSprite.y = Starling.current.stage.stageHeight/ 1.5; - + skeletonSprite.state.setAnimationByName(0, "shake", true); addChild(skeletonSprite); diff --git a/spine-haxe/example/src/TankExample.hx b/spine-haxe/example/src/starlingExamples/TankExample.hx similarity index 97% rename from spine-haxe/example/src/TankExample.hx rename to spine-haxe/example/src/starlingExamples/TankExample.hx index 52e6f39ff..aa8b35885 100644 --- a/spine-haxe/example/src/TankExample.hx +++ b/spine-haxe/example/src/starlingExamples/TankExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; diff --git a/spine-haxe/example/src/Test.hx b/spine-haxe/example/src/starlingExamples/Test.hx similarity index 97% rename from spine-haxe/example/src/Test.hx rename to spine-haxe/example/src/starlingExamples/Test.hx index 4edbc69b0..59e0eb713 100644 --- a/spine-haxe/example/src/Test.hx +++ b/spine-haxe/example/src/starlingExamples/Test.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.animation.AnimationStateData; diff --git a/spine-haxe/example/src/VineExample.hx b/spine-haxe/example/src/starlingExamples/VineExample.hx similarity index 97% rename from spine-haxe/example/src/VineExample.hx rename to spine-haxe/example/src/starlingExamples/VineExample.hx index 6b174086a..5a317261c 100644 --- a/spine-haxe/example/src/VineExample.hx +++ b/spine-haxe/example/src/starlingExamples/VineExample.hx @@ -27,7 +27,9 @@ * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ -import Scene.SceneManager; +package starlingExamples; + +import starlingExamples.Scene.SceneManager; import openfl.utils.Assets; import spine.SkeletonData; import spine.Physics; diff --git a/spine-haxe/haxelib.json b/spine-haxe/haxelib.json index 78328344e..7f698369e 100644 --- a/spine-haxe/haxelib.json +++ b/spine-haxe/haxelib.json @@ -17,8 +17,8 @@ "cpp" ], "description": "The official Spine Runtime for Haxe", - "version": "4.2.3", - "releasenote": "Update to 4.2.3", + "version": "4.2.5", + "releasenote": "Update to 4.2.5", "contributors": [ "esotericsoftware" ], diff --git a/spine-haxe/project.xml b/spine-haxe/project.xml index 85f1a9d4b..6b4423862 100644 --- a/spine-haxe/project.xml +++ b/spine-haxe/project.xml @@ -3,10 +3,13 @@ + + + diff --git a/spine-haxe/spine-haxe/spine/Skin.hx b/spine-haxe/spine-haxe/spine/Skin.hx index 769cdddac..56e9da5aa 100644 --- a/spine-haxe/spine-haxe/spine/Skin.hx +++ b/spine-haxe/spine-haxe/spine/Skin.hx @@ -228,13 +228,15 @@ class Skin { var slotAttachment:Attachment = slot.attachment; if (slotAttachment != null && slotIndex < oldSkin.attachments.length) { var dictionary:StringMap = oldSkin.attachments[slotIndex]; - for (name in dictionary.keys()) { - var skinAttachment:Attachment = dictionary.get(name); - if (slotAttachment == skinAttachment) { - var attachment:Attachment = getAttachment(slotIndex, name); - if (attachment != null) - slot.attachment = attachment; - break; + if (null != dictionary) { + for (name in dictionary.keys()) { + var skinAttachment:Attachment = dictionary.get(name); + if (slotAttachment == skinAttachment) { + var attachment:Attachment = getAttachment(slotIndex, name); + if (attachment != null) + slot.attachment = attachment; + break; + } } } } diff --git a/spine-haxe/spine-haxe/spine/flixel/FlixelTextureLoader.hx b/spine-haxe/spine-haxe/spine/flixel/FlixelTextureLoader.hx new file mode 100644 index 000000000..b672b1b14 --- /dev/null +++ b/spine-haxe/spine-haxe/spine/flixel/FlixelTextureLoader.hx @@ -0,0 +1,72 @@ +/****************************************************************************** + * 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 spine.flixel; + +import flixel.graphics.FlxGraphic; +import flixel.FlxG; +import spine.atlas.TextureAtlasPage; +import spine.atlas.TextureAtlasRegion; +import spine.atlas.TextureLoader; +import spine.flixel.SpineTexture; + +class FlixelTextureLoader implements TextureLoader +{ + private var basePath:String; + + public function new(prefix:String) { + basePath = ""; + var slashIndex = prefix.lastIndexOf("/"); + if (slashIndex != -1) { + basePath = prefix.substring(0, slashIndex); + } + } + + public function loadPage(page:TextureAtlasPage, path:String):Void + { + var bitmapData = openfl.utils.Assets.getBitmapData(basePath + "/" + path); + if (bitmapData == null) { + throw new SpineException("Could not load atlas page texture " + basePath + "/" + path); + } + var texture:FlxGraphic = SpineTexture.from(bitmapData); + // TODO: reset this value to true when destroy skeleton + // this is needed for sequence, otherwise the previous texture would be detroyed + texture.destroyOnNoUse = false; + page.texture = texture; + } + + public function loadRegion(region:TextureAtlasRegion):Void { + region.texture = region.page.texture; + } + + public function unloadPage(page:TextureAtlasPage):Void + { + FlxG.bitmap.remove(cast page.texture); + } +} \ No newline at end of file diff --git a/spine-haxe/spine-haxe/spine/flixel/SkeletonMesh.hx b/spine-haxe/spine-haxe/spine/flixel/SkeletonMesh.hx new file mode 100644 index 000000000..92052745f --- /dev/null +++ b/spine-haxe/spine-haxe/spine/flixel/SkeletonMesh.hx @@ -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 spine.flixel; + +import flixel.FlxStrip; + +// this class is just to make the implementation coherent with the starling implementation +class SkeletonMesh extends FlxStrip { + public function new(/*texture:FlxGraphicAsset*/) { + super(); + // graphic = texture; + } +} diff --git a/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx b/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx new file mode 100644 index 000000000..be750d193 --- /dev/null +++ b/spine-haxe/spine-haxe/spine/flixel/SkeletonSprite.hx @@ -0,0 +1,382 @@ +package spine.flixel; + +import openfl.geom.Point; +import flixel.math.FlxPoint; +import flixel.math.FlxMatrix; +import spine.animation.MixDirection; +import spine.animation.MixBlend; +import spine.animation.Animation; +import spine.TextureRegion; +import haxe.extern.EitherType; +import spine.attachments.Attachment; +import flixel.util.typeLimit.OneOfTwo; +import flixel.FlxCamera; +import flixel.math.FlxRect; +import flixel.FlxG; +import flixel.FlxObject; +import flixel.FlxSprite; +import flixel.FlxStrip; +import flixel.group.FlxSpriteGroup; +import flixel.graphics.FlxGraphic; +import flixel.util.FlxColor; +import openfl.Vector; +import openfl.display.BlendMode; +import spine.Bone; +import spine.Skeleton; +import spine.SkeletonData; +import spine.Slot; +import spine.animation.AnimationState; +import spine.animation.AnimationStateData; +import spine.atlas.TextureAtlasRegion; +import spine.attachments.MeshAttachment; +import spine.attachments.RegionAttachment; +import spine.attachments.ClippingAttachment; +import spine.flixel.SkeletonMesh; + +class SkeletonSprite extends FlxObject +{ + public var skeleton(default, null):Skeleton; + public var state(default, null):AnimationState; + public var stateData(default, null):AnimationStateData; + public var beforeUpdateWorldTransforms: SkeletonSprite -> Void = function(_) {}; + public var afterUpdateWorldTransforms: SkeletonSprite -> Void = function(_) {}; + public static var clipper(default, never):SkeletonClipping = new SkeletonClipping(); + + public var offsetX = .0; + public var offsetY = .0; + public var alpha = 1.; // TODO: clamp + public var color:FlxColor = 0xffffff; + public var flipX(default, set):Bool = false; + public var flipY(default, set):Bool = false; + public var antialiasing:Bool = true; + + @:isVar + public var scaleX(get, set):Float = 1; + @:isVar + public var scaleY(get, set):Float = 1; + + var _tempVertices:Array = new Array(); + var _quadTriangles:Array; + var _meshes(default, null):Array = new Array(); + + private var _tempMatrix = new FlxMatrix(); + private var _tempPoint = new Point(); + + private static var QUAD_INDICES:Array = [0, 1, 2, 2, 3, 0]; + public function new(skeletonData:SkeletonData, animationStateData:AnimationStateData = null) + { + super(0, 0); + Bone.yDown = true; + skeleton = new Skeleton(skeletonData); + skeleton.updateWorldTransform(Physics.update); + state = new AnimationState(animationStateData != null ? animationStateData : new AnimationStateData(skeletonData)); + setBoundingBox(); + } + + public function setBoundingBox(?animation:Animation, ?clip:Bool = true) { + var bounds = animation == null ? skeleton.getBounds() : getAnimationBounds(animation, clip); + if (bounds.width > 0 && bounds.height > 0) { + width = bounds.width; + height = bounds.height; + offsetX = -bounds.x; + offsetY = -bounds.y; + } + } + + public function getAnimationBounds(animation:Animation, clip:Bool = true): lime.math.Rectangle { + var clipper = clip ? SkeletonSprite.clipper : null; + skeleton.setToSetupPose(); + + var steps = 100, time = 0.; + var stepTime = animation.duration != 0 ? animation.duration / steps : 0; + var minX = 100000000., maxX = -100000000., minY = 100000000., maxY = -100000000.; + + var bounds = new lime.math.Rectangle(); + for (i in 0...steps) { + animation.apply(skeleton, time , time, false, [], 1, MixBlend.setup, MixDirection.mixIn); + skeleton.updateWorldTransform(Physics.update); + bounds = skeleton.getBounds(clipper); + + if (!Math.isNaN(bounds.x) && !Math.isNaN(bounds.y) && !Math.isNaN(bounds.width) && !Math.isNaN(bounds.height)) { + minX = Math.min(bounds.x, minX); + minY = Math.min(bounds.y, minY); + maxX = Math.max(bounds.right, maxX); + maxY = Math.max(bounds.bottom, maxY); + } else + trace("ERROR"); + + time += stepTime; + } + bounds.x = minX; + bounds.y = minY; + bounds.width = maxX - minX; + bounds.height = maxY - minY; + return bounds; + } + + override public function destroy():Void + { + skeleton = null; + state = null; + stateData = null; + + _tempVertices = null; + _quadTriangles = null; + _tempMatrix = null; + _tempPoint = null; + + if (_meshes != null) { + for (mesh in _meshes) mesh.destroy(); + _meshes = null; + } + + super.destroy(); + } + + override public function update(elapsed:Float):Void + { + super.update(elapsed); + state.update(elapsed); + state.apply(skeleton); + this.beforeUpdateWorldTransforms(this); + skeleton.update(elapsed); + skeleton.updateWorldTransform(Physics.update); + this.afterUpdateWorldTransforms(this); + } + + override public function draw():Void + { + if (alpha == 0) return; + + renderMeshes(); + + #if FLX_DEBUG + if (FlxG.debugger.drawDebug) drawDebug(); + #end + } + + function renderMeshes():Void { + var clipper:SkeletonClipping = SkeletonSprite.clipper; + var drawOrder:Array = skeleton.drawOrder; + var attachmentColor:spine.Color; + var mesh:SkeletonMesh = null; + var numVertices:Int; + var numFloats:Int; + var triangles:Array = null; + var uvs:Array; + var twoColorTint:Bool = false; + var vertexSize:Int = twoColorTint ? 12 : 8; + _tempMatrix = getTransformMatrix(); + for (slot in drawOrder) { + var clippedVertexSize:Int = clipper.isClipping() ? 2 : vertexSize; + if (!slot.bone.active) { + clipper.clipEndWithSlot(slot); + continue; + } + + var worldVertices:Array = _tempVertices; + if (Std.isOfType(slot.attachment, RegionAttachment)) { + var region:RegionAttachment = cast(slot.attachment, RegionAttachment); + numVertices = 4; + numFloats = clippedVertexSize << 2; + if (numFloats > worldVertices.length) { + worldVertices.resize(numFloats); + } + region.computeWorldVertices(slot, worldVertices, 0, clippedVertexSize); + + mesh = getFlixelMeshFromRendererAttachment(region); + mesh.graphic = region.region.texture; + triangles = QUAD_INDICES; + uvs = region.uvs; + attachmentColor = region.color; + } else if (Std.isOfType(slot.attachment, MeshAttachment)) { + var meshAttachment:MeshAttachment = cast(slot.attachment, MeshAttachment); + numVertices = meshAttachment.worldVerticesLength >> 1; + numFloats = numVertices * clippedVertexSize; // 8 for now because I'm excluding clipping + if (numFloats > worldVertices.length) { + worldVertices.resize(numFloats); + } + meshAttachment.computeWorldVertices(slot, 0, meshAttachment.worldVerticesLength, worldVertices, 0, clippedVertexSize); + + mesh = getFlixelMeshFromRendererAttachment(meshAttachment); + mesh.graphic = meshAttachment.region.texture; + triangles = meshAttachment.triangles; + uvs = meshAttachment.uvs; + attachmentColor = meshAttachment.color; + } else if (Std.isOfType(slot.attachment, ClippingAttachment)) { + var clip:ClippingAttachment = cast(slot.attachment, ClippingAttachment); + clipper.clipStart(slot, clip); + continue; + } else { + clipper.clipEndWithSlot(slot); + continue; + } + + if (mesh != null) { + + // cannot use directly mesh.color.setRGBFloat otherwise the setter won't be called and transfor color not set + mesh.color = FlxColor.fromRGBFloat( + skeleton.color.r * slot.color.r * attachmentColor.r * color.redFloat, + skeleton.color.g * slot.color.g * attachmentColor.g * color.greenFloat, + skeleton.color.b * slot.color.b * attachmentColor.b * color.blueFloat, + 1 + ); + mesh.alpha = skeleton.color.a * slot.color.a * attachmentColor.a * alpha; + + if (clipper.isClipping()) { + clipper.clipTriangles(worldVertices, triangles, triangles.length, uvs); + + mesh.indices = Vector.ofArray(clipper.clippedTriangles); + mesh.uvtData = Vector.ofArray(clipper.clippedUvs); + + if (angle == 0) { + mesh.vertices = Vector.ofArray(clipper.clippedVertices); + mesh.x = x + offsetX; + mesh.y = y + offsetY; + } else { + var i = 0; + mesh.vertices.length = clipper.clippedVertices.length; + while (i < mesh.vertices.length) { + _tempPoint.setTo(clipper.clippedVertices[i], clipper.clippedVertices[i + 1]); + _tempPoint = _tempMatrix.transformPoint(_tempPoint); + mesh.vertices[i] = _tempPoint.x; + mesh.vertices[i + 1] = _tempPoint.y; + i+=2; + } + } + } else { + var v = 0; + var n = numFloats; + var i = 0; + mesh.vertices.length = numVertices; + while (v < n) { + if (angle == 0) { + mesh.vertices[i] = worldVertices[v]; + mesh.vertices[i + 1] = worldVertices[v + 1]; + } else { + _tempPoint.setTo(worldVertices[v], worldVertices[v + 1]); + _tempPoint = _tempMatrix.transformPoint(_tempPoint); + mesh.vertices[i] = _tempPoint.x; + mesh.vertices[i + 1] = _tempPoint.y; + } + v += 8; + i += 2; + } + if (angle == 0) { + mesh.x = x + offsetX; + mesh.y = y + offsetY; + } + mesh.indices = Vector.ofArray(triangles); + mesh.uvtData = Vector.ofArray(uvs); + } + + mesh.antialiasing = antialiasing; + mesh.blend = SpineTexture.toFlixelBlending(slot.data.blendMode); + // x/y position works for mesh, but angle does not work. + // if the transformation matrix is moved into the FlxStrip draw and used there + // we can just put vertices without doing any transformation + // mesh.x = x + offsetX; + // mesh.y = y + offsetY; + // mesh.angle = angle; + mesh.draw(); + } + + clipper.clipEndWithSlot(slot); + } + clipper.clipEnd(); + } + + private function getTransformMatrix():FlxMatrix { + _tempMatrix.identity(); + // scale is connected to the skeleton scale - no need to rescale + _tempMatrix.scale(1, 1); + _tempMatrix.rotate(angle * Math.PI / 180); + _tempMatrix.translate(x + offsetX, y + offsetY); + return _tempMatrix; + } + + public function skeletonToHaxeWorldCoordinates(point:Array):Void { + var transform = getTransformMatrix(); + var a = transform.a, + b = transform.b, + c = transform.c, + d = transform.d, + tx = transform.tx, + ty = transform.ty; + var x = point[0]; + var y = point[1]; + point[0] = x * a + y * c + tx; + point[1] = x * b + y * d + ty; + } + + public function haxeWorldCoordinatesToSkeleton(point:Array):Void { + var transform = getTransformMatrix().invert(); + var a = transform.a, + b = transform.b, + c = transform.c, + d = transform.d, + tx = transform.tx, + ty = transform.ty; + var x = point[0]; + var y = point[1]; + point[0] = x * a + y * c + tx; + point[1] = x * b + y * d + ty; + } + + public function haxeWorldCoordinatesToBone(point:Array, bone: Bone):Void { + this.haxeWorldCoordinatesToSkeleton(point); + if (bone.parent != null) { + bone.parent.worldToLocal(point); + } else { + bone.worldToLocal(point); + } + } + + private function getFlixelMeshFromRendererAttachment(region: RenderedAttachment) { + if (region.rendererObject == null) { + var skeletonMesh = new SkeletonMesh(); + region.rendererObject = skeletonMesh; + skeletonMesh.exists = false; + _meshes.push(skeletonMesh); + } + return region.rendererObject; + } + + function set_flipX(value:Bool):Bool + { + if (value != flipX) skeleton.scaleX = -skeleton.scaleX; + return flipX = value; + } + + function set_flipY(value:Bool):Bool + { + if (value != flipY) skeleton.scaleY = -skeleton.scaleY; + return flipY = value; + } + + function set_scale(value:FlxPoint):FlxPoint { + return value; + } + + function get_scaleX():Float { + return skeleton.scaleX; + } + + function set_scaleX(value:Float):Float { + return skeleton.scaleX = value; + } + + function get_scaleY():Float { + return skeleton.scaleY; + } + + function set_scaleY(value:Float):Float { + return skeleton.scaleY = value; + } + +} + +typedef RenderedAttachment = { + var rendererObject:Dynamic; + var region:TextureRegion; +} \ No newline at end of file diff --git a/spine-haxe/spine-haxe/spine/flixel/SpineTexture.hx b/spine-haxe/spine-haxe/spine/flixel/SpineTexture.hx new file mode 100644 index 000000000..c1d807024 --- /dev/null +++ b/spine-haxe/spine-haxe/spine/flixel/SpineTexture.hx @@ -0,0 +1,30 @@ +package spine.flixel; + +import flixel.FlxG; +import flixel.graphics.FlxGraphic; +import openfl.display.BlendMode; + +class SpineTexture extends FlxGraphic +{ + public static function from(bitmapData: openfl.display.BitmapData): FlxGraphic { + return FlxG.bitmap.add(bitmapData); + } + + public static function toFlixelBlending (blend: spine.BlendMode): BlendMode { + switch (blend) { + case spine.BlendMode.normal: + return BlendMode.NORMAL; + + case spine.BlendMode.additive: + return BlendMode.ADD; + + case spine.BlendMode.multiply: + return BlendMode.MULTIPLY; + + case spine.BlendMode.screen: + return BlendMode.SCREEN; + } + return BlendMode.NORMAL; + } + +} diff --git a/spine-ios/Sources/Spine/BoundsProvider.swift b/spine-ios/Sources/Spine/BoundsProvider.swift index 99130336d..e2b3ca56a 100644 --- a/spine-ios/Sources/Spine/BoundsProvider.swift +++ b/spine-ios/Sources/Spine/BoundsProvider.swift @@ -59,7 +59,7 @@ public final class SkinAndAnimationBounds: NSObject, BoundsProvider { /// the bounding box of the skeleton. If no skins are given, the default skin is used. /// The `stepTime`, given in seconds, defines at what interval the bounds should be sampled /// across the entire animation. - public init(animation: String? = nil, skins: [String]? = nil, let stepTime: TimeInterval = 0.1) { + public init(animation: String? = nil, skins: [String]? = nil, stepTime: TimeInterval = 0.1) { self.animation = animation if let skins, !skins.isEmpty { self.skins = skins diff --git a/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift b/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift index 9a48e4770..ac0e6437b 100644 --- a/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift +++ b/spine-ios/Sources/Spine/Extensions/SkeletonDrawableWrapper+CGImage.swift @@ -27,7 +27,7 @@ public extension SkeletonDrawableWrapper { spineView.delegate?.draw(in: spineView) guard let texture = spineView.currentDrawable?.texture else { - throw "Could not read texture." + throw SpineError("Could not read texture.") } let width = texture.width let height = texture.height @@ -47,7 +47,7 @@ public extension SkeletonDrawableWrapper { let colorSpace = CGColorSpaceCreateDeviceRGB() guard let context = CGContext(data: data, width: width, height: height, bitsPerComponent: 8, bytesPerRow: rowBytes, space: colorSpace, bitmapInfo: bitmapInfo.rawValue), let cgImage = context.makeImage() else { - throw "Could not create image." + throw SpineError("Could not create image.") } return cgImage } diff --git a/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift b/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift index b87e5dd06..b5c28dbc2 100644 --- a/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift +++ b/spine-ios/Sources/Spine/SkeletonDrawableWrapper.swift @@ -94,22 +94,22 @@ public final class SkeletonDrawableWrapper: NSObject { self.skeletonData = skeletonData guard let nativeSkeletonDrawable = spine_skeleton_drawable_create(skeletonData.wrappee) else { - throw "Could not load native skeleton drawable" + throw SpineError("Could not load native skeleton drawable") } skeletonDrawable = SkeletonDrawable(nativeSkeletonDrawable) guard let nativeSkeleton = spine_skeleton_drawable_get_skeleton(skeletonDrawable.wrappee) else { - throw "Could not load native skeleton" + throw SpineError("Could not load native skeleton") } skeleton = Skeleton(nativeSkeleton) guard let nativeAnimationStateData = spine_skeleton_drawable_get_animation_state_data(skeletonDrawable.wrappee) else { - throw "Could not load native animation state data" + throw SpineError("Could not load native animation state data") } animationStateData = AnimationStateData(nativeAnimationStateData) guard let nativeAnimationState = spine_skeleton_drawable_get_animation_state(skeletonDrawable.wrappee) else { - throw "Could not load native animation state" + throw SpineError("Could not load native animation state") } animationState = AnimationState(nativeAnimationState) animationStateWrapper = AnimationStateWrapper( diff --git a/spine-ios/Sources/Spine/Spine.Generated+Extensions.swift b/spine-ios/Sources/Spine/Spine.Generated+Extensions.swift index 64b222673..5f616d2c5 100644 --- a/spine-ios/Sources/Spine/Spine.Generated+Extensions.swift +++ b/spine-ios/Sources/Spine/Spine.Generated+Extensions.swift @@ -57,18 +57,19 @@ public extension Atlas { } private static func fromData(data: Data, loadFile: (_ name: String) async throws -> Data) async throws -> (Atlas, [UIImage]) { - guard let atlasData = String(data: data, encoding: .utf8) as? NSString else { - throw "Couldn't read atlas bytes as utf8 string" + guard let atlasData = String(data: data, encoding: .utf8) else { + throw SpineError("Couldn't read atlas bytes as utf8 string") } - let atlasDataNative = UnsafeMutablePointer(mutating: atlasData.utf8String) - guard let atlas = spine_atlas_load(atlasDataNative) else { - throw "Couldn't load atlas data" + let atlas = try atlasData.utf8CString.withUnsafeBufferPointer { + guard let atlas = spine_atlas_load($0.baseAddress) else { + throw SpineError("Couldn't load atlas data") + } + return atlas } - if let error = spine_atlas_get_error(atlas) { let message = String(cString: error) spine_atlas_dispose(atlas) - throw "Couldn't load atlas: \(message)" + throw SpineError("Couldn't load atlas: \(message)") } var atlasPages = [UIImage]() @@ -130,26 +131,31 @@ public extension SkeletonData { /// /// Throws an `Error` in case the skeleton data could not be loaded. static func fromData(atlas: Atlas, data: Data) throws -> SkeletonData { - let binaryNative = try data.withUnsafeBytes { unsafeBytes in - guard let bytes = unsafeBytes.bindMemory(to: UInt8.self).baseAddress else { - throw "Couldn't read atlas binary" + let result = try data.withUnsafeBytes{ + try $0.withMemoryRebound(to: UInt8.self) { buffer in + guard let ptr = buffer.baseAddress else { + throw SpineError("Couldn't read atlas binary") + } + return spine_skeleton_data_load_binary( + atlas.wrappee, + ptr, + Int32(buffer.count) + ) } - return (data: bytes, length: Int32(unsafeBytes.count)) } - let result = spine_skeleton_data_load_binary( - atlas.wrappee, - binaryNative.data, - binaryNative.length - ) + guard let result else { + throw SpineError("Couldn't load skeleton data") + } + defer { + spine_skeleton_data_result_dispose(result) + } if let error = spine_skeleton_data_result_get_error(result) { let message = String(cString: error) - spine_skeleton_data_result_dispose(result) - throw "Couldn't load skeleton data: \(message)" + throw SpineError("Couldn't load skeleton data: \(message)") } guard let data = spine_skeleton_data_result_get_data(result) else { - throw "Couldn't load skeleton data from result" + throw SpineError("Couldn't load skeleton data from result") } - spine_skeleton_data_result_dispose(result) return SkeletonData(data) } @@ -158,26 +164,31 @@ public extension SkeletonData { /// /// Throws an `Error` in case the atlas could not be loaded. static func fromJson(atlas: Atlas, json: String) throws -> SkeletonData { - let jsonNative = UnsafeMutablePointer(mutating: (json as NSString).utf8String) - guard let result = spine_skeleton_data_load_json(atlas.wrappee, jsonNative) else { - throw "Couldn't load skeleton data json" + let result = try json.utf8CString.withUnsafeBufferPointer { buffer in + guard + let basePtr = buffer.baseAddress, + let result = spine_skeleton_data_load_json(atlas.wrappee, basePtr) else { + throw SpineError("Couldn't load skeleton data json") + } + return result + } + defer { + spine_skeleton_data_result_dispose(result) } if let error = spine_skeleton_data_result_get_error(result) { let message = String(cString: error) - spine_skeleton_data_result_dispose(result) - throw "Couldn't load skeleton data: \(message)" + throw SpineError("Couldn't load skeleton data: \(message)") } guard let data = spine_skeleton_data_result_get_data(result) else { - throw "Couldn't load skeleton data from result" + throw SpineError("Couldn't load skeleton data from result") } - spine_skeleton_data_result_dispose(result) return SkeletonData(data) } private static func fromData(atlas: Atlas, data: Data, isJson: Bool) throws -> SkeletonData { if isJson { guard let json = String(data: data, encoding: .utf8) else { - throw "Couldn't read skeleton data json string" + throw SpineError("Couldn't read skeleton data json string") } return try fromJson(atlas: atlas, json: json) } else { @@ -271,12 +282,12 @@ internal enum FileSource { case .bundle(let fileName, let bundle): let components = fileName.split(separator: ".") guard components.count > 1, let ext = components.last else { - throw "Provide both file name and file extension" + throw SpineError("Provide both file name and file extension") } let name = components.dropLast(1).joined(separator: ".") guard let fileUrl = bundle.url(forResource: name, withExtension: String(ext)) else { - throw "Could not load file with name \(name) from bundle" + throw SpineError("Could not load file with name \(name) from bundle") } return try Data(contentsOf: fileUrl, options: []) case .file(let fileUrl): @@ -289,34 +300,63 @@ internal enum FileSource { } return try Data(contentsOf: temp, options: []) } else { - return try await withCheckedThrowingContinuation { continuation in - let task = URLSession.shared.downloadTask(with: url) { temp, response, error in - if let error { - continuation.resume(throwing: error) - } else { - guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { - continuation.resume(throwing: URLError(.badServerResponse)) - return - } - guard let temp else { - continuation.resume(throwing: "Could not download file.") - return - } - do { - continuation.resume(returning: try Data(contentsOf: temp, options: [])) - } catch { + let lock = NSRecursiveLock() + nonisolated(unsafe) + var isCancelled = false + nonisolated(unsafe) + var taskHolder:URLSessionDownloadTask? = nil + return try await withTaskCancellationHandler { + try await withCheckedThrowingContinuation { continuation in + let task = URLSession.shared.downloadTask(with: url) { temp, response, error in + if let error { continuation.resume(throwing: error) + } else { + guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + continuation.resume(throwing: URLError(.badServerResponse)) + return + } + guard let temp else { + continuation.resume(throwing: SpineError("Could not download file.")) + return + } + do { + continuation.resume(returning: try Data(contentsOf: temp, options: [])) + } catch { + continuation.resume(throwing: error) + } } } + task.resume() + let shouldCancel = lock.withLock { + if !isCancelled { + taskHolder = task + } + return isCancelled + } + if shouldCancel { + task.cancel() + } } - task.resume() + } onCancel: { + lock.withLock { + isCancelled = true + let value = taskHolder + taskHolder = nil + return value + }?.cancel() } } } } } -extension String: Error { +public struct SpineError: Error, CustomStringConvertible { + + public let description: String + + internal init(_ description: String) { + self.description = description + } } diff --git a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java index d850bad72..463bcfc3f 100644 --- a/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java +++ b/spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java @@ -180,18 +180,16 @@ public class AnimationState { from.animationLast = from.nextAnimationLast; from.trackLast = from.nextTrackLast; - if (to.nextTrackLast != -1) { // The from entry was applied at least once. - boolean discard = to.mixTime == 0 && from.mixTime == 0; // Discard the from entry when neither have advanced yet. - if (to.mixTime >= to.mixDuration || discard) { - // Require totalAlpha == 0 to ensure mixing is complete or the transition is a single frame or discarded. - if (from.totalAlpha == 0 || to.mixDuration == 0 || discard) { - to.mixingFrom = from.mixingFrom; - if (from.mixingFrom != null) from.mixingFrom.mixingTo = to; - to.interruptAlpha = from.interruptAlpha; - queue.end(from); - } - return finished; + // The from entry was applied at least once and the mix is complete. + if (to.nextTrackLast != -1 && to.mixTime >= to.mixDuration) { + // Mixing is complete for all entries before the from entry or the mix is instantaneous. + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + queue.end(from); } + return finished; } from.trackTime += delta * from.timeScale; diff --git a/spine-ts/package-lock.json b/spine-ts/package-lock.json index 19d1544cf..8c5586c0f 100644 --- a/spine-ts/package-lock.json +++ b/spine-ts/package-lock.json @@ -1,12 +1,12 @@ { "name": "@esotericsoftware/spine-ts", - "version": "4.2.73", + "version": "4.2.76", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@esotericsoftware/spine-ts", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "workspaces": [ "spine-core", @@ -3142,18 +3142,18 @@ }, "spine-canvas": { "name": "@esotericsoftware/spine-canvas", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73" + "@esotericsoftware/spine-core": "4.2.76" } }, "spine-canvaskit": { "name": "@esotericsoftware/spine-canvaskit", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73", + "@esotericsoftware/spine-core": "4.2.76", "canvaskit-wasm": "0.39.1" }, "devDependencies": { @@ -3163,17 +3163,17 @@ }, "spine-core": { "name": "@esotericsoftware/spine-core", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE" }, "spine-phaser": { "name": "@esotericsoftware/spine-phaser", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-canvas": "4.2.73", - "@esotericsoftware/spine-core": "4.2.73", - "@esotericsoftware/spine-webgl": "4.2.73" + "@esotericsoftware/spine-canvas": "4.2.76", + "@esotericsoftware/spine-core": "4.2.76", + "@esotericsoftware/spine-webgl": "4.2.76" }, "peerDependencies": { "phaser": "^3.60.0" @@ -3181,10 +3181,10 @@ }, "spine-pixi-v7": { "name": "@esotericsoftware/spine-pixi-v7", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73" + "@esotericsoftware/spine-core": "4.2.76" }, "peerDependencies": { "@pixi/assets": "^7.2.4", @@ -3198,10 +3198,10 @@ }, "spine-pixi-v8": { "name": "@esotericsoftware/spine-pixi-v8", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73" + "@esotericsoftware/spine-core": "4.2.76" }, "peerDependencies": { "pixi.js": "^8.4.0" @@ -3209,18 +3209,18 @@ }, "spine-player": { "name": "@esotericsoftware/spine-player", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-webgl": "4.2.73" + "@esotericsoftware/spine-webgl": "4.2.76" } }, "spine-threejs": { "name": "@esotericsoftware/spine-threejs", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73" + "@esotericsoftware/spine-core": "4.2.76" }, "devDependencies": { "@types/three": "0.162.0" @@ -3231,10 +3231,10 @@ }, "spine-webgl": { "name": "@esotericsoftware/spine-webgl", - "version": "4.2.73", + "version": "4.2.76", "license": "LicenseRef-LICENSE", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73" + "@esotericsoftware/spine-core": "4.2.76" } } } diff --git a/spine-ts/package.json b/spine-ts/package.json index 7f4f29287..cb4110e51 100644 --- a/spine-ts/package.json +++ b/spine-ts/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-ts", - "version": "4.2.73", + "version": "4.2.76", "description": "The official Spine Runtimes for the web.", "type": "module", "files": [ diff --git a/spine-ts/spine-canvas/package.json b/spine-ts/spine-canvas/package.json index 31705eb0f..3d35b5b42 100644 --- a/spine-ts/spine-canvas/package.json +++ b/spine-ts/spine-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-canvas", - "version": "4.2.73", + "version": "4.2.76", "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.73" + "@esotericsoftware/spine-core": "4.2.76" } } \ No newline at end of file diff --git a/spine-ts/spine-canvaskit/package.json b/spine-ts/spine-canvaskit/package.json index d492ba5ad..4b1a0ec39 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.73", + "version": "4.2.76", "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.73", + "@esotericsoftware/spine-core": "4.2.76", "canvaskit-wasm": "0.39.1" }, "devDependencies": { diff --git a/spine-ts/spine-core/package.json b/spine-ts/spine-core/package.json index d15c5a0f9..3aebf72ff 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.73", + "version": "4.2.76", "description": "The official Spine Runtimes for the web.", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/spine-ts/spine-phaser/package.json b/spine-ts/spine-phaser/package.json index 62ca2fac8..ebf943c3d 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.73", + "version": "4.2.76", "description": "The official Spine Runtimes for the Phaser.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -31,9 +31,9 @@ }, "homepage": "https://github.com/esotericsoftware/spine-runtimes#readme", "dependencies": { - "@esotericsoftware/spine-core": "4.2.73", - "@esotericsoftware/spine-webgl": "4.2.73", - "@esotericsoftware/spine-canvas": "4.2.73" + "@esotericsoftware/spine-core": "4.2.76", + "@esotericsoftware/spine-webgl": "4.2.76", + "@esotericsoftware/spine-canvas": "4.2.76" }, "peerDependencies": { "phaser": "^3.60.0" diff --git a/spine-ts/spine-phaser/src/SpinePlugin.ts b/spine-ts/spine-phaser/src/SpinePlugin.ts index ba8b91419..8c3b4fe4b 100644 --- a/spine-ts/spine-phaser/src/SpinePlugin.ts +++ b/spine-ts/spine-phaser/src/SpinePlugin.ts @@ -122,22 +122,42 @@ export class SpinePlugin extends Phaser.Plugins.ScenePlugin { }; pluginManager.registerFileType("spineAtlas", atlasFileCallback, scene); - let self = this; let addSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, x: number, y: number, dataKey: string, atlasKey: string, boundsProvider: SpineGameObjectBoundsProvider) { - let gameObject = new SpineGameObject(this.scene, self, x, y, dataKey, atlasKey, boundsProvider); + if (this.scene.sys.renderer instanceof Phaser.Renderer.WebGL.WebGLRenderer) { + this.scene.sys.renderer.pipelines.clear(); + } + + const spinePlugin = (this.scene.sys as any)[pluginKey] as SpinePlugin; + let gameObject = new SpineGameObject(this.scene, spinePlugin, x, y, dataKey, atlasKey, boundsProvider); this.displayList.add(gameObject); this.updateList.add(gameObject); + + if (this.scene.sys.renderer instanceof Phaser.Renderer.WebGL.WebGLRenderer) { + this.scene.sys.renderer.pipelines.rebind(); + } + return gameObject; }; let makeSpineGameObject = function (this: Phaser.GameObjects.GameObjectFactory, config: SpineGameObjectConfig, addToScene: boolean = false) { + if (this.scene.sys.renderer instanceof Phaser.Renderer.WebGL.WebGLRenderer) { + this.scene.sys.renderer.pipelines.clear(); + } + let x = config.x ? config.x : 0; let y = config.y ? config.y : 0; let boundsProvider = config.boundsProvider ? config.boundsProvider : undefined; - let gameObject = new SpineGameObject(this.scene, self, x, y, config.dataKey, config.atlasKey, boundsProvider); + + const spinePlugin = (this.scene.sys as any)[pluginKey] as SpinePlugin; + let gameObject = new SpineGameObject(this.scene, spinePlugin, x, y, config.dataKey, config.atlasKey, boundsProvider); if (addToScene !== undefined) { config.add = addToScene; } + + if (this.scene.sys.renderer instanceof Phaser.Renderer.WebGL.WebGLRenderer) { + this.scene.sys.renderer.pipelines.rebind(); + } + return Phaser.GameObjects.BuildGameObject(this.scene, gameObject, config); } pluginManager.registerGameObject((window as any).SPINE_GAME_OBJECT_TYPE ? (window as any).SPINE_GAME_OBJECT_TYPE : SPINE_GAME_OBJECT_TYPE, addSpineGameObject, makeSpineGameObject); diff --git a/spine-ts/spine-phaser/src/mixins.ts b/spine-ts/spine-phaser/src/mixins.ts index 83c2dc0d1..7f12789b0 100644 --- a/spine-ts/spine-phaser/src/mixins.ts +++ b/spine-ts/spine-phaser/src/mixins.ts @@ -59,7 +59,7 @@ export function createMixin< }; } -type ComputedSizeMixin = Mixin; +type ComputedSizeMixin = Mixin; export const ComputedSizeMixin: ComputedSizeMixin = createMixin(ComputedSize); type DepthMixin = Mixin; diff --git a/spine-ts/spine-pixi-v7/package.json b/spine-ts/spine-pixi-v7/package.json index 46b52111a..d4d207fc8 100644 --- a/spine-ts/spine-pixi-v7/package.json +++ b/spine-ts/spine-pixi-v7/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-pixi-v7", - "version": "4.2.73", + "version": "4.2.76", "description": "The official Spine Runtimes for the web PixiJS v7.", "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.73" + "@esotericsoftware/spine-core": "4.2.76" }, "peerDependencies": { "@pixi/core": "^7.2.4", diff --git a/spine-ts/spine-pixi-v8/package.json b/spine-ts/spine-pixi-v8/package.json index 26cf3d06c..3741121b8 100644 --- a/spine-ts/spine-pixi-v8/package.json +++ b/spine-ts/spine-pixi-v8/package.json @@ -1,6 +1,6 @@ { "name": "@esotericsoftware/spine-pixi-v8", - "version": "4.2.73", + "version": "4.2.76", "description": "The official Spine Runtimes for PixiJS v8.", "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.73" + "@esotericsoftware/spine-core": "4.2.76" }, "peerDependencies": { "pixi.js": "^8.4.0" diff --git a/spine-ts/spine-pixi-v8/src/Spine.ts b/spine-ts/spine-pixi-v8/src/Spine.ts index 6870300ce..75afa9b56 100644 --- a/spine-ts/spine-pixi-v8/src/Spine.ts +++ b/spine-ts/spine-pixi-v8/src/Spine.ts @@ -560,6 +560,7 @@ export class Spine extends ViewContainer { this.spineAttachmentsDirty ||= spineAttachmentsDirty; } + private currentClippingSlot: SlotsToClipping | undefined; private updateAndSetPixiMask (slot: Slot, last: boolean) { // assign/create the currentClippingSlot const attachment = slot.attachment; @@ -614,10 +615,10 @@ export class Spine extends ViewContainer { clippingSlotToPixiMask.mask = undefined; } } + this.currentClippingSlot = undefined; } } - private currentClippingSlot: SlotsToClipping | undefined; private transformAttachments () { const currentDrawOrder = this.skeleton.drawOrder; diff --git a/spine-ts/spine-player/package.json b/spine-ts/spine-player/package.json index 01d39db82..a807e042a 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.73", + "version": "4.2.76", "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.73" + "@esotericsoftware/spine-webgl": "4.2.76" } } \ No newline at end of file diff --git a/spine-ts/spine-player/src/Player.ts b/spine-ts/spine-player/src/Player.ts index 2ae8273ea..3fcc764b1 100644 --- a/spine-ts/spine-player/src/Player.ts +++ b/spine-ts/spine-player/src/Player.ts @@ -347,7 +347,7 @@ export class SpinePlayer implements Disposable { this.sceneRenderer = new SceneRenderer(this.canvas, this.context, true); if (config.showLoading) this.loadingScreen = new LoadingScreen(this.sceneRenderer); } catch (e) { - this.showError("Sorry, your browser does not support WebG, or you have disabled WebGL in your browser settings.\nPlease use the latest version of Firefox, Chrome, Edge, or Safari.", e as any); + this.showError("Sorry, your browser does not support WebGL, or you have disabled WebGL in your browser settings.\nPlease use the latest version of Firefox, Chrome, Edge, or Safari.", e as any); return null; } diff --git a/spine-ts/spine-threejs/package.json b/spine-ts/spine-threejs/package.json index a415ff4d7..f471562f3 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.73", + "version": "4.2.76", "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.73" + "@esotericsoftware/spine-core": "4.2.76" }, "devDependencies": { "@types/three": "0.162.0" diff --git a/spine-ts/spine-threejs/src/MeshBatcher.ts b/spine-ts/spine-threejs/src/MeshBatcher.ts index 36307f97c..1e72634f9 100644 --- a/spine-ts/spine-threejs/src/MeshBatcher.ts +++ b/spine-ts/spine-threejs/src/MeshBatcher.ts @@ -309,7 +309,7 @@ const spineOnBeforeCompile = (shader: THREE.WebGLProgramParametersWithUniforms) #ifdef USE_SPINE_DARK_TINT #ifdef USE_COLOR_ALPHA diffuseColor.a *= vColor.a; - diffuseColor.rgb *= (1.0 - diffuseColor.rgb) * v_dark.rgb + diffuseColor.rgb * vColor.rgb; + diffuseColor.rgb = (diffuseColor.a - diffuseColor.rgb) * v_dark.rgb + diffuseColor.rgb * vColor.rgb; #endif #else #ifdef USE_COLOR_ALPHA diff --git a/spine-ts/spine-threejs/src/SkeletonMesh.ts b/spine-ts/spine-threejs/src/SkeletonMesh.ts index 1d335ec8d..797af709e 100644 --- a/spine-ts/spine-threejs/src/SkeletonMesh.ts +++ b/spine-ts/spine-threejs/src/SkeletonMesh.ts @@ -294,7 +294,7 @@ export class SkeletonMesh extends THREE.Object3D { let darkColor = this.tempDarkColor; if (!slot.darkColor) - darkColor.set(1, 1, 1, 0); + darkColor.set(0, 0, 0, 1); else { darkColor.r = slot.darkColor.r * alpha; darkColor.g = slot.darkColor.g * alpha; diff --git a/spine-ts/spine-webgl/package.json b/spine-ts/spine-webgl/package.json index 8f000285c..aab54bda4 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.73", + "version": "4.2.76", "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.73" + "@esotericsoftware/spine-core": "4.2.76" } } \ No newline at end of file diff --git a/spine-ts/spine-webgl/tests/test-binary.html b/spine-ts/spine-webgl/tests/test-binary.html index 3c9088004..a4b721611 100644 --- a/spine-ts/spine-webgl/tests/test-binary.html +++ b/spine-ts/spine-webgl/tests/test-binary.html @@ -98,7 +98,7 @@ function render() { var start = Date.now() timeKeeper.update(); - var delta = 0.016; // timeKeeper.delta; + var delta = timeKeeper.delta; for (var i = 0; i < skeletons.length; i++) { var state = skeletons[i].state; diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/RenderExistingMeshGraphic.cs b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/RenderExistingMeshGraphic.cs new file mode 100644 index 000000000..518419c03 --- /dev/null +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/RenderExistingMeshGraphic.cs @@ -0,0 +1,224 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2025, 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. + *****************************************************************************/ + +#if UNITY_2018_3 || UNITY_2019 || UNITY_2018_3_OR_NEWER +#define NEW_PREFAB_SYSTEM +#endif + +#if UNITY_2018_2_OR_NEWER +#define HAS_CULL_TRANSPARENT_MESH +#endif + +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace Spine.Unity.Examples { + using MaterialReplacement = RenderExistingMesh.MaterialReplacement; + +#if NEW_PREFAB_SYSTEM + [ExecuteAlways] +#else + [ExecuteInEditMode] +#endif + public class RenderExistingMeshGraphic : MonoBehaviour { + public SkeletonGraphic referenceSkeletonGraphic; + public Material replacementMaterial; + + public MaterialReplacement[] replacementMaterials = new MaterialReplacement[0]; + + SkeletonSubmeshGraphic ownGraphic; + public List ownSubmeshGraphics; + +#if UNITY_EDITOR + private void Reset () { + Awake(); + LateUpdate(); + } +#endif + + void Awake () { + // subscribe to OnMeshAndMaterialsUpdated + if (referenceSkeletonGraphic) { + referenceSkeletonGraphic.OnMeshAndMaterialsUpdated -= UpdateOnCallback; + referenceSkeletonGraphic.OnMeshAndMaterialsUpdated += UpdateOnCallback; + } + + ownGraphic = this.GetComponent(); + if (referenceSkeletonGraphic) { + if (referenceSkeletonGraphic.allowMultipleCanvasRenderers) + EnsureCanvasRendererCount(referenceSkeletonGraphic.canvasRenderers.Count); + else + SetupSubmeshGraphic(); + } + } + + protected void OnDisable () { + if (referenceSkeletonGraphic) { + referenceSkeletonGraphic.OnMeshAndMaterialsUpdated -= UpdateOnCallback; + } + } + + protected void OnEnable () { +#if UNITY_EDITOR + // handle disabled scene reload + if (Application.isPlaying) { + Awake(); + return; + } +#endif + if (referenceSkeletonGraphic) { + referenceSkeletonGraphic.OnMeshAndMaterialsUpdated -= UpdateOnCallback; + referenceSkeletonGraphic.OnMeshAndMaterialsUpdated += UpdateOnCallback; + } + } + + void SetupSubmeshGraphic () { + if (ownGraphic == null) + ownGraphic = this.gameObject.AddComponent(); + + ownGraphic.maskable = referenceSkeletonGraphic.maskable; +#if HAS_CULL_TRANSPARENT_MESH + ownGraphic.canvasRenderer.cullTransparentMesh = referenceSkeletonGraphic.canvasRenderer.cullTransparentMesh; +#endif + ownGraphic.canvasRenderer.SetMaterial(replacementMaterial, referenceSkeletonGraphic.mainTexture); + } + + protected void EnsureCanvasRendererCount (int targetCount) { + if (ownSubmeshGraphics == null) + ownSubmeshGraphics = new List(); + +#if HAS_CULL_TRANSPARENT_MESH + bool cullTransparentMesh = referenceSkeletonGraphic.canvasRenderer.cullTransparentMesh; +#endif + Vector2 pivot = referenceSkeletonGraphic.rectTransform.pivot; + + int currentCount = ownSubmeshGraphics.Count; + for (int i = currentCount; i < targetCount; ++i) { + GameObject go = new GameObject(string.Format("Renderer{0}", i), typeof(RectTransform)); + go.transform.SetParent(this.transform, false); + go.transform.localPosition = Vector3.zero; + CanvasRenderer canvasRenderer = go.AddComponent(); +#if HAS_CULL_TRANSPARENT_MESH + canvasRenderer.cullTransparentMesh = cullTransparentMesh; +#endif + SkeletonSubmeshGraphic submeshGraphic = go.AddComponent(); + ownSubmeshGraphics.Add(submeshGraphic); + submeshGraphic.maskable = referenceSkeletonGraphic.maskable; + submeshGraphic.raycastTarget = false; + submeshGraphic.rectTransform.pivot = pivot; + submeshGraphic.rectTransform.anchorMin = Vector2.zero; + submeshGraphic.rectTransform.anchorMax = Vector2.one; + submeshGraphic.rectTransform.sizeDelta = Vector2.zero; + } + } + + protected void UpdateCanvasRenderers () { + Mesh[] referenceMeshes = referenceSkeletonGraphic.MeshesMultipleCanvasRenderers.Items; + Material[] referenceMaterials = referenceSkeletonGraphic.MaterialsMultipleCanvasRenderers.Items; + Texture[] referenceTextures = referenceSkeletonGraphic.TexturesMultipleCanvasRenderers.Items; + + int end = Math.Min(ownSubmeshGraphics.Count, referenceSkeletonGraphic.TexturesMultipleCanvasRenderers.Count); + + for (int i = 0; i < end; i++) { + SkeletonSubmeshGraphic submeshGraphic = ownSubmeshGraphics[i]; + CanvasRenderer reference = referenceSkeletonGraphic.canvasRenderers[i]; + + if (reference.gameObject.activeInHierarchy) { + Material usedMaterial = replacementMaterial != null ? + replacementMaterial : GetReplacementMaterialFor(referenceMaterials[i]); + if (usedMaterial == null) + usedMaterial = referenceMaterials[i]; + usedMaterial = referenceSkeletonGraphic.GetModifiedMaterial(usedMaterial); + submeshGraphic.canvasRenderer.SetMaterial(usedMaterial, referenceTextures[i]); + submeshGraphic.canvasRenderer.SetMesh(referenceMeshes[i]); + submeshGraphic.gameObject.SetActive(true); + } else { + submeshGraphic.canvasRenderer.Clear(); + submeshGraphic.gameObject.SetActive(false); + } + } + } + + protected void DisableCanvasRenderers () { + for (int i = 0; i < ownSubmeshGraphics.Count; i++) { + SkeletonSubmeshGraphic submeshGraphic = ownSubmeshGraphics[i]; + submeshGraphic.canvasRenderer.Clear(); + submeshGraphic.gameObject.SetActive(false); + } + } + + protected Material GetReplacementMaterialFor (Material originalMaterial) { + for (int i = 0; i < replacementMaterials.Length; ++i) { + MaterialReplacement entry = replacementMaterials[i]; + if (entry.originalMaterial != null && entry.originalMaterial.shader == originalMaterial.shader) + return entry.replacementMaterial; + } + return null; + } + +#if UNITY_EDITOR + void LateUpdate () { + if (!Application.isPlaying) { + UpdateMesh(); + } + } +#endif + + void UpdateOnCallback (SkeletonGraphic g) { + UpdateMesh(); + } + + void UpdateMesh () { + if (!referenceSkeletonGraphic) return; + + if (referenceSkeletonGraphic.allowMultipleCanvasRenderers) { + EnsureCanvasRendererCount(referenceSkeletonGraphic.canvasRenderers.Count); + UpdateCanvasRenderers(); + if (ownGraphic) + ownGraphic.canvasRenderer.Clear(); + } else { + if (ownGraphic == null) + ownGraphic = this.gameObject.AddComponent(); + + DisableCanvasRenderers(); + + Material referenceMaterial = referenceSkeletonGraphic.materialForRendering; + Material usedMaterial = replacementMaterial != null ? replacementMaterial : GetReplacementMaterialFor(referenceMaterial); + if (usedMaterial == null) + usedMaterial = referenceMaterial; + usedMaterial = referenceSkeletonGraphic.GetModifiedMaterial(usedMaterial); + ownGraphic.canvasRenderer.SetMaterial(usedMaterial, referenceSkeletonGraphic.mainTexture); + Mesh mesh = referenceSkeletonGraphic.GetLastMesh(); + ownGraphic.canvasRenderer.SetMesh(mesh); + } + } + } +} diff --git a/spine-unity/Assets/Spine Examples/Scripts/Sample Components/RenderExistingMeshGraphic.cs.meta b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/RenderExistingMeshGraphic.cs.meta new file mode 100644 index 000000000..ca0fdd068 --- /dev/null +++ b/spine-unity/Assets/Spine Examples/Scripts/Sample Components/RenderExistingMeshGraphic.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ff6ce4ce6b9336a479c6bf5af81fa80a \ No newline at end of file diff --git a/spine-unity/Assets/Spine Examples/package.json b/spine-unity/Assets/Spine Examples/package.json index 9f15b3a28..5c19a8500 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.37", + "version": "4.2.38", "unity": "2018.3", "author": { "name": "Esoteric Software", diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs index effb6d9ef..9d4c6d367 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs +++ b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Shaders/SpineShaderWithOutlineGUI.cs @@ -41,6 +41,7 @@ public class SpineShaderWithOutlineGUI : ShaderGUI { MaterialProperty _OutlineWidth = null; MaterialProperty _UseScreenSpaceOutlineWidth = null; MaterialProperty _OutlineColor = null; + MaterialProperty _Fill = null; MaterialProperty _OutlineReferenceTexWidth = null; MaterialProperty _ThresholdEnd = null; MaterialProperty _OutlineSmoothness = null; @@ -54,6 +55,7 @@ public class SpineShaderWithOutlineGUI : ShaderGUI { static GUIContent _OutlineWidthText = new GUIContent("Outline Width", ""); static GUIContent _UseScreenSpaceOutlineWidthText = new GUIContent("Width in Screen Space", "Enable to keep the outline width constant in screen space instead of texture space. Requires more expensive computations."); static GUIContent _OutlineColorText = new GUIContent("Outline Color", ""); + static GUIContent _FillText = new GUIContent("Fill", "Enable to also fill the opaque area inside the outline with the outline color. Prevents a semi-transparent gap between outline and skeleton."); static GUIContent _OutlineReferenceTexWidthText = new GUIContent("Reference Texture Width", ""); static GUIContent _ThresholdEndText = new GUIContent("Outline Threshold", ""); static GUIContent _OutlineSmoothnessText = new GUIContent("Outline Smoothness", ""); @@ -92,6 +94,7 @@ public class SpineShaderWithOutlineGUI : ShaderGUI { _UseScreenSpaceOutlineWidth = FindProperty("_UseScreenSpaceOutlineWidth", props, false); _OutlineReferenceTexWidth = FindProperty("_OutlineReferenceTexWidth", props, false); _OutlineColor = FindProperty("_OutlineColor", props, false); + _Fill = FindProperty("_Fill", props, false); _ThresholdEnd = FindProperty("_ThresholdEnd", props, false); _OutlineSmoothness = FindProperty("_OutlineSmoothness", props, false); _Use8Neighbourhood = FindProperty("_Use8Neighbourhood", props, false); @@ -157,6 +160,8 @@ public class SpineShaderWithOutlineGUI : ShaderGUI { if (_UseScreenSpaceOutlineWidth != null) _materialEditor.ShaderProperty(_UseScreenSpaceOutlineWidth, _UseScreenSpaceOutlineWidthText); _materialEditor.ShaderProperty(_OutlineColor, _OutlineColorText); + if (_Fill != null) + _materialEditor.ShaderProperty(_Fill, _FillText); _showAdvancedOutlineSettings = EditorGUILayout.Foldout(_showAdvancedOutlineSettings, _OutlineAdvancedText); if (_showAdvancedOutlineSettings) { diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader index 7da343e05..a9cb2cbc3 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Additive.shader @@ -18,6 +18,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Additive" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader index 0454ffcfb..574facd0d 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Multiply.shader @@ -18,6 +18,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Multiply" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader index b39c9cf7e..53298c69c 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/BlendModes/Spine-Skeleton-PMA-Screen.shader @@ -18,6 +18,7 @@ Shader "Spine/Blend Modes/Skeleton PMA Screen" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Outline-Common.cginc b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Outline-Common.cginc index ae3763848..f82ce6e09 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Outline-Common.cginc +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/CGIncludes/Spine-Outline-Common.cginc @@ -46,8 +46,13 @@ float4 computeOutlinePixel(sampler2D mainTexture, float2 mainTextureTexelSize, float average = (pixelTop + pixelBottom + pixelLeft + pixelRight) * vertexColorAlpha / numSamples; #endif float thresholdStart = ThresholdEnd * (1.0 - OutlineSmoothness); - float outlineAlpha = saturate(saturate((average - thresholdStart) / (ThresholdEnd - thresholdStart)) - pixelCenter); - outlineAlpha = pixelCenter > OutlineOpaqueAlpha ? 0 : outlineAlpha; + float outlineAlpha = saturate((average - thresholdStart) / (ThresholdEnd - thresholdStart)); +#if !_OUTLINE_FILL_INSIDE + outlineAlpha = saturate(outlineAlpha - pixelCenter); + outlineAlpha = pixelCenter > OutlineOpaqueAlpha ? 0.0 : outlineAlpha; +#else + outlineAlpha = pixelCenter > OutlineOpaqueAlpha ? 1.0 : outlineAlpha; +#endif return lerp(texColor, OutlineColor, outlineAlpha); } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader index 56a176967..d4cb13fc3 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Additive-Outline.shader @@ -13,6 +13,7 @@ Shader "Spine/Outline/Blend Modes/Skeleton PMA Additive" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader index c008d45a1..9c1fd3ed5 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Multiply-Outline.shader @@ -13,6 +13,7 @@ Shader "Spine/Outline/Blend Modes/Skeleton PMA Multiply" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader index cdd7bd7ca..07b8edcee 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/BlendModes/Spine-Skeleton-PMA-Screen-Outline.shader @@ -13,6 +13,7 @@ Shader "Spine/Outline/Blend Modes/Skeleton PMA Screen" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader index b899d9d03..6ef6cb083 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-Outline.shader @@ -23,6 +23,7 @@ Shader "Spine/Outline/SkeletonGraphic" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader index 51647cb3f..3ab6749de 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/SkeletonGraphic/Spine-SkeletonGraphic-TintBlack-Outline.shader @@ -25,6 +25,7 @@ Shader "Spine/Outline/SkeletonGraphic Tint Black" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader index 0c00f2368..1c3da7f93 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Fill-Outline.shader @@ -14,6 +14,7 @@ Shader "Spine/Outline/Skeleton Fill" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader index 358b6b79a..ccdc0a8be 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-Outline.shader @@ -13,6 +13,7 @@ Shader "Spine/Outline/Skeleton Lit" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader index 055c6fa71..195fe8c75 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Lit-ZWrite-Outline.shader @@ -14,6 +14,7 @@ Shader "Spine/Outline/Skeleton Lit ZWrite" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader index ab5e01914..4e6aed0b8 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Outline.shader @@ -12,6 +12,7 @@ Shader "Spine/Outline/Skeleton" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 @@ -42,6 +43,7 @@ Shader "Spine/Outline/Skeleton" { #pragma fragment fragOutline #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON #pragma shader_feature _ _USE_SCREENSPACE_OUTLINE_WIDTH + #pragma shader_feature _ _OUTLINE_FILL_INSIDE #include "CGIncludes/Spine-Outline-Pass.cginc" ENDCG } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader index 16743f185..e1f7c0390 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite.shader @@ -11,6 +11,7 @@ Shader "Spine/Outline/OutlineOnly-ZWrite" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 @@ -56,6 +57,7 @@ Shader "Spine/Outline/OutlineOnly-ZWrite" { #pragma fragment fragOutline #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON #pragma shader_feature _ _USE_SCREENSPACE_OUTLINE_WIDTH + #pragma shader_feature _ _OUTLINE_FILL_INSIDE #include "CGIncludes/Spine-Outline-Pass.cginc" ENDCG } diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader index c9d179a30..c0a87690a 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-Tint-Outline.shader @@ -14,6 +14,7 @@ Shader "Spine/Outline/Skeleton Tint" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader index 7b608ac9e..7edad607e 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Skeleton-TintBlack-Outline.shader @@ -14,6 +14,7 @@ Shader "Spine/Outline/Skeleton Tint Black" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader index eaf9ca60a..de6c1c901 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Spine-Special-Skeleton-Grayscale-Outline.shader @@ -13,6 +13,7 @@ Shader "Spine/Outline/Special/Skeleton Grayscale" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader index ce6a98166..91c172e17 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesPixelLit-Outline.shader @@ -50,6 +50,7 @@ Shader "Spine/Outline/Sprite/Pixel Lit" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader index 64a6805cb..28a73a100 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesUnlit-Outline.shader @@ -33,6 +33,7 @@ Shader "Spine/Outline/Sprite/Unlit" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader index 7ca7fdf5d..2ff861430 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Outline/Sprite/SpritesVertexLit-Outline.shader @@ -51,6 +51,7 @@ Shader "Spine/Outline/Sprite/Vertex Lit" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Additive.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Additive.shader index a90833f3c..6d0862f07 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Additive.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Additive.shader @@ -23,6 +23,7 @@ Shader "Spine/SkeletonGraphic Additive" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Fill.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Fill.shader index 53078f062..dbc3dc3a9 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Fill.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Fill.shader @@ -23,6 +23,7 @@ Shader "Spine/SkeletonGraphic Fill" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Grayscale.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Grayscale.shader index dc8cfe0d2..6499e4f7c 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Grayscale.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Grayscale.shader @@ -21,6 +21,7 @@ Shader "Spine/SkeletonGraphic Grayscale" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Multiply.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Multiply.shader index 4e6fde069..5ebecc1ee 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Multiply.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Multiply.shader @@ -23,6 +23,7 @@ Shader "Spine/SkeletonGraphic Multiply" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Screen.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Screen.shader index b25c69c8d..e7953b944 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Screen.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic-Screen.shader @@ -23,6 +23,7 @@ Shader "Spine/SkeletonGraphic Screen" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader index 82a377d26..0932e5e34 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/Spine-SkeletonGraphic.shader @@ -23,6 +23,7 @@ Shader "Spine/SkeletonGraphic" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Additive.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Additive.shader index 3bd624f81..b569b7663 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Additive.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Additive.shader @@ -24,6 +24,7 @@ Shader "Spine/SkeletonGraphic Tint Black Additive" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Multiply.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Multiply.shader index 61987b1b9..a5285776b 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Multiply.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Multiply.shader @@ -24,6 +24,7 @@ Shader "Spine/SkeletonGraphic Tint Black Multiply" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Screen.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Screen.shader index c1a4c2518..56e0ed5a0 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Screen.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack-Screen.shader @@ -24,6 +24,7 @@ Shader "Spine/SkeletonGraphic Tint Black Screen" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack.shader index 6babb5895..678ac9a38 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/SkeletonGraphic/TintBlack/Spine-SkeletonGraphic-TintBlack.shader @@ -24,6 +24,7 @@ Shader "Spine/SkeletonGraphic Tint Black" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader index a7669c8e0..af7ba9c49 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Fill.shader @@ -16,6 +16,7 @@ Shader "Spine/Skeleton Fill" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader index b0c57acd0..2f33d2f2a 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit-ZWrite.shader @@ -17,6 +17,7 @@ Shader "Spine/Skeleton Lit ZWrite" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader index f3d10ee03..f01806f93 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Lit.shader @@ -16,6 +16,7 @@ Shader "Spine/Skeleton Lit" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader index 56feb518e..424dcf6da 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-Tint.shader @@ -19,6 +19,7 @@ Shader "Spine/Skeleton Tint" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader index 4fbbbbba2..32883491c 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton-TintBlack.shader @@ -21,6 +21,7 @@ Shader "Spine/Skeleton Tint Black" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader index 304de737e..708a50a01 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Skeleton.shader @@ -10,6 +10,7 @@ Shader "Spine/Skeleton" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader index 367808693..a2f361880 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Spine-Special-Skeleton-Grayscale.shader @@ -15,6 +15,7 @@ Shader "Spine/Special/Skeleton Grayscale" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader index 1dbe6efae..8910d40c6 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesPixelLit.shader @@ -52,6 +52,7 @@ Shader "Spine/Sprite/Pixel Lit" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader index 7549dd85e..124586ea1 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesUnlit.shader @@ -34,6 +34,7 @@ Shader "Spine/Sprite/Unlit" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader index cd15a4e4e..45e8f7a81 100644 --- a/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader +++ b/spine-unity/Assets/Spine/Runtime/spine-unity/Shaders/Sprite/SpritesVertexLit.shader @@ -53,6 +53,7 @@ Shader "Spine/Sprite/Vertex Lit" [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 diff --git a/spine-unity/Assets/Spine/package.json b/spine-unity/Assets/Spine/package.json index ac683c326..6ee911457 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.98", + "version": "4.2.99", "unity": "2018.3", "author": { "name": "Esoteric Software", diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-URP.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-URP.shader index 482cb890f..b3cf2acbe 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-URP.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-URP.shader @@ -8,6 +8,7 @@ Shader "Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 @@ -46,6 +47,7 @@ Shader "Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly" { #pragma fragment fragOutline #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON #pragma shader_feature _ _USE_SCREENSPACE_OUTLINE_WIDTH + #pragma shader_feature _ _OUTLINE_FILL_INSIDE #define USE_URP #define fixed4 half4 diff --git a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite-URP.shader b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite-URP.shader index 7c1c03b6b..55375ff65 100644 --- a/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite-URP.shader +++ b/spine-unity/Modules/com.esotericsoftware.spine.urp-shaders/Shaders/Outline/Spine-Skeleton-OutlineOnly-ZWrite-URP.shader @@ -9,6 +9,7 @@ Shader "Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly ZWrite" { [HideInInspector] _OutlineWidth("Outline Width", Range(0,8)) = 3.0 [HideInInspector][MaterialToggle(_USE_SCREENSPACE_OUTLINE_WIDTH)] _UseScreenSpaceOutlineWidth("Width in Screen Space", Float) = 0 [HideInInspector] _OutlineColor("Outline Color", Color) = (1,1,0,1) + [HideInInspector][MaterialToggle(_OUTLINE_FILL_INSIDE)]_Fill("Fill", Float) = 0 [HideInInspector] _OutlineReferenceTexWidth("Reference Texture Width", Int) = 1024 [HideInInspector] _ThresholdEnd("Outline Threshold", Range(0,1)) = 0.25 [HideInInspector] _OutlineSmoothness("Outline Smoothness", Range(0,1)) = 1.0 @@ -50,6 +51,7 @@ Shader "Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly ZWrite" { #pragma fragment fragOutline #pragma shader_feature _ _USE8NEIGHBOURHOOD_ON #pragma shader_feature _ _USE_SCREENSPACE_OUTLINE_WIDTH + #pragma shader_feature _ _OUTLINE_FILL_INSIDE #define USE_URP #define fixed4 half4 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 e11e59022..4724b1a95 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.41", + "version": "4.2.42", "unity": "2019.3", "author": { "name": "Esoteric Software",