Merge branch '4.1' into 4.2-beta

# Conflicts:
#	spine-cocos2dx/README.md
#	spine-godot/spine_godot/SpineSprite.cpp
#	spine-sdl/src/spine-sdl-cpp.cpp
#	spine-sfml/cpp/src/spine/spine-sfml.cpp
This commit is contained in:
Mario Zechner 2022-09-15 08:39:43 +02:00
commit c590944a51
16 changed files with 81 additions and 37 deletions

View File

@ -595,7 +595,8 @@ _spAnimationState_setAttachment(spAnimationState *self, spSkeleton *skeleton, sp
/* @param target After the first and before the last entry. */ /* @param target After the first and before the last entry. */
static int binarySearch1(float *values, int valuesLength, float target) { static int binarySearch1(float *values, int valuesLength, float target) {
for (int i = 1; i < valuesLength; i++) { int i;
for (i = 1; i < valuesLength; i++) {
if (values[i] > target) return (int) (i - 1); if (values[i] > target) return (int) (i - 1);
} }
return (int) valuesLength - 1; return (int) valuesLength - 1;

View File

@ -79,22 +79,39 @@ spRegionAttachment *spRegionAttachment_create(const char *name) {
} }
void spRegionAttachment_updateRegion(spRegionAttachment *self) { void spRegionAttachment_updateRegion(spRegionAttachment *self) {
float regionScaleX = self->width / self->region->originalWidth * self->scaleX; float regionScaleX, regionScaleY, localX, localY, localX2, localY2;
float regionScaleY = self->height / self->region->originalHeight * self->scaleY; float radians, cosine, sine;
float localX = -self->width / 2 * self->scaleX + self->region->offsetX * regionScaleX; float localXCos, localXSin, localYCos, localYSin, localX2Cos, localX2Sin, localY2Cos, localY2Sin;
float localY = -self->height / 2 * self->scaleY + self->region->offsetY * regionScaleY;
float localX2 = localX + self->region->width * regionScaleX; if (self->region == NULL) {
float localY2 = localY + self->region->height * regionScaleY; self->uvs[0] = 0;
float radians = self->rotation * DEG_RAD; self->uvs[1] = 0;
float cosine = COS(radians), sine = SIN(radians); self->uvs[2] = 1;
float localXCos = localX * cosine + self->x; self->uvs[3] = 1;
float localXSin = localX * sine; self->uvs[4] = 1;
float localYCos = localY * cosine + self->y; self->uvs[5] = 0;
float localYSin = localY * sine; self->uvs[6] = 0;
float localX2Cos = localX2 * cosine + self->x; self->uvs[7] = 0;
float localX2Sin = localX2 * sine; return;
float localY2Cos = localY2 * cosine + self->y; }
float localY2Sin = localY2 * sine;
regionScaleX = self->width / self->region->originalWidth * self->scaleX;
regionScaleY = self->height / self->region->originalHeight * self->scaleY;
localX = -self->width / 2 * self->scaleX + self->region->offsetX * regionScaleX;
localY = -self->height / 2 * self->scaleY + self->region->offsetY * regionScaleY;
localX2 = localX + self->region->width * regionScaleX;
localY2 = localY + self->region->height * regionScaleY;
radians = self->rotation * DEG_RAD;
cosine = COS(radians), sine = SIN(radians);
localXCos = localX * cosine + self->x;
localXSin = localX * sine;
localYCos = localY * cosine + self->y;
localYSin = localY * sine;
localX2Cos = localX2 * cosine + self->x;
localX2Sin = localX2 * sine;
localY2Cos = localY2 * cosine + self->y;
localY2Sin = localY2 * sine;
self->offset[BLX] = localXCos - localYSin; self->offset[BLX] = localXCos - localYSin;
self->offset[BLY] = localYCos + localXSin; self->offset[BLY] = localYCos + localXSin;
self->offset[ULX] = localXCos - localY2Sin; self->offset[ULX] = localXCos - localY2Sin;

View File

@ -437,7 +437,6 @@ void spSkeleton_updateWorldTransformWith(const spSkeleton *self, const spBone *p
/* Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. */ /* Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. */
int i; int i;
float rotationY, la, lb, lc, ld; float rotationY, la, lb, lc, ld;
_spUpdate *updateCache;
_spSkeleton *internal = SUB_CAST(_spSkeleton, self); _spSkeleton *internal = SUB_CAST(_spSkeleton, self);
spBone *rootBone = self->root; spBone *rootBone = self->root;
float pa = parent->a, pb = parent->b, pc = parent->c, pd = parent->d; float pa = parent->a, pb = parent->b, pc = parent->c, pd = parent->d;
@ -455,7 +454,6 @@ void spSkeleton_updateWorldTransformWith(const spSkeleton *self, const spBone *p
CONST_CAST(float, rootBone->d) = (pc * lb + pd * ld) * self->scaleY; CONST_CAST(float, rootBone->d) = (pc * lb + pd * ld) * self->scaleY;
/* Update everything except root bone. */ /* Update everything except root bone. */
updateCache = internal->updateCache;
for (i = 0; i < internal->updateCacheCount; ++i) { for (i = 0; i < internal->updateCacheCount; ++i) {
_spUpdate *update = internal->updateCache + i; _spUpdate *update = internal->updateCache + i;
switch (update->type) { switch (update->type) {

View File

@ -68,13 +68,13 @@ Execute the following on the command line:
``` ```
cd spine-runtimes/spine-cocos2dx/example cd spine-runtimes/spine-cocos2dx/example
mkdir build-macos && cmake . -GXcode -Bbuild-macos mkdir build-macos && cmake . -GXcode -Bbuild-macos -DCMAKE_OSX_ARCHITECTURES=x86_64
open build-macos/spine-cocos2dx-example.xcodeproj open build-macos/spine-cocos2dx-example.xcodeproj
``` ```
This will generate an Xcode project in `build-macos/spine-cocos2dx-example.xcodeproj` and open it in Xcode. To build and run the example, select the `spine-cocos2dx-example` scheme and press `CMD + R`. This will generate an Xcode project in `build-macos/spine-cocos2dx-example.xcodeproj` and open it in Xcode. To build and run the example, select the `spine-cocos2dx-example` scheme and press `CMD + R`.
> **Note**: cocos2d-x only ships pre-built external libraries like Bullet or FreeType for x86_64. If you build on a machine with Apple Silicon, adjust the `cmake` command above to `mkdir build-macos && cmake . -GXcode -Bbuild-macos -DCMAKE_OSX_ARCHITECTURES=x86_64`. > **NOTE:** Passing `-DCMAKE_OSX_ARCHITECTURES=x86_64` to CMake is currently required, as Cocos2d-X only provides prebuilt x86_64 binaries for its external dependencies.
### iOS ### iOS
Execute the following on the command line: Execute the following on the command line:

View File

@ -68,6 +68,18 @@ RegionAttachment::~RegionAttachment() {
} }
void RegionAttachment::updateRegion() { void RegionAttachment::updateRegion() {
if (_region == NULL) {
_uvs[BLX] = 0;
_uvs[BLY] = 0;
_uvs[ULX] = 0;
_uvs[ULY] = 1;
_uvs[URX] = 1;
_uvs[URY] = 1;
_uvs[BRX] = 1;
_uvs[BRY] = 0;
return;
}
float regionScaleX = _width / _region->originalWidth * _scaleX; float regionScaleX = _width / _region->originalWidth * _scaleX;
float regionScaleY = _height / _region->originalHeight * _scaleY; float regionScaleY = _height / _region->originalHeight * _scaleY;
float localX = -_width / 2 * _scaleX + _region->offsetX * regionScaleX; float localX = -_width / 2 * _scaleX + _region->offsetX * regionScaleX;

View File

@ -97,7 +97,7 @@ namespace Spine {
if (region == null) { if (region == null) {
uvs[BLX] = 0; uvs[BLX] = 0;
uvs[BLY] = 0; uvs[BLY] = 0;
uvs[ULX] = 1; uvs[ULX] = 0;
uvs[ULY] = 1; uvs[ULY] = 1;
uvs[URX] = 1; uvs[URX] = 1;
uvs[URY] = 1; uvs[URY] = 1;

View File

@ -552,10 +552,10 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) { if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
auto *region = (spine::RegionAttachment *) attachment; auto *region = (spine::RegionAttachment *) attachment;
renderer_object = (SpineRendererObject *) region->getRegion()->rendererObject;
vertices->setSize(8, 0); vertices->setSize(8, 0);
region->computeWorldVertices(*slot, *vertices, 0); region->computeWorldVertices(*slot, *vertices, 0);
renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) region->getRendererObject())->page->getRendererObject();
uvs = &region->getUVs(); uvs = &region->getUVs();
indices = &quad_indices; indices = &quad_indices;
@ -566,10 +566,10 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
tint.a *= attachment_color.a; tint.a *= attachment_color.a;
} else if (attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) { } else if (attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) {
auto *mesh = (spine::MeshAttachment *) attachment; auto *mesh = (spine::MeshAttachment *) attachment;
renderer_object = (SpineRendererObject *) mesh->getRegion()->rendererObject;
vertices->setSize(mesh->getWorldVerticesLength(), 0); vertices->setSize(mesh->getWorldVerticesLength(), 0);
mesh->computeWorldVertices(*slot, *vertices); mesh->computeWorldVertices(*slot, *vertices);
renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) mesh->getRendererObject())->page->getRendererObject();
uvs = &mesh->getUVs(); uvs = &mesh->getUVs();
indices = &mesh->getTriangles(); indices = &mesh->getTriangles();

View File

@ -84,7 +84,7 @@ public class RegionAttachment extends Attachment implements HasTextureRegion {
if (region == null) { if (region == null) {
uvs[BLX] = 0; uvs[BLX] = 0;
uvs[BLY] = 0; uvs[BLY] = 0;
uvs[ULX] = 1; uvs[ULX] = 0;
uvs[ULY] = 1; uvs[ULY] = 1;
uvs[URX] = 1; uvs[URX] = 1;
uvs[URY] = 1; uvs[URY] = 1;

View File

@ -26,7 +26,7 @@ spine-sdl supports all Spine features except premultiplied alpha, screen blend m
1. Create a new SDL project. See the [SDL documentation](https://wiki.libsdl.org/FrontPage) or have a look at the example in this repository. 1. Create a new SDL project. See the [SDL documentation](https://wiki.libsdl.org/FrontPage) or have a look at the example in this repository.
2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above. 2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above.
3. If you are using C, add the sources from `spine-c/spine-c/src/spine` and `spine-sdl/src/spine-sdl-c.c` to your project, and add the folder `spine-c/spine-c/include` and `spine-sdl/src/spine-sdl-c.h` to your header search path. Note that includes are specified as `#inclue <spine/file.h>`, so the `spine` directory cannot be omitted when copying the source files. 3. If you are using C, add the sources from `spine-c/spine-c/src/spine` and `spine-sdl/src/spine-sdl-c.c` to your project, and add the folder `spine-c/spine-c/include` and `spine-sdl/src/spine-sdl-c.h` to your header search path. Note that includes are specified as `#inclue <spine/file.h>`, so the `spine` directory cannot be omitted when copying the source files.
3. If you are using C++, add the sources from `spine-cpp/spine-cpp/src/spine` and `spine-sdl/src/spine-sdl-cpp.cpp` to your project, and add the folder `spine-cpp/spine-cpp/include` and `spine-sdl/src/spine-sdl-cpp.h` to your header search path. Note that includes are specified as `#inclue <spine/file.h>`, so the `spine` directory cannot be omitted when copying the source files. 3. If you are using C++, add the sources from `spine-cpp/spine-cpp/src/spine` and `spine-sdl/src/spine-sdl-cpp.cpp` to your project, and add the folder `spine-cpp/spine-cpp/include` and `spine-sdl/src/spine-sdl-cpp.h` to your header search path. Note that includes are specified as `#include <spine/file.h>`, so the `spine` directory cannot be omitted when copying the source files.
See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine SDL example in this repository. See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine SDL example in this repository.

View File

@ -114,8 +114,8 @@ void SkeletonDrawable::draw(SDL_Renderer *renderer) {
} }
worldVertices.setSize(mesh->getWorldVerticesLength(), 0); worldVertices.setSize(mesh->getWorldVerticesLength(), 0);
texture = (SDL_Texture *) mesh->getRegion()->rendererObject;
mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices.buffer(), 0, 2); mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices.buffer(), 0, 2);
texture = (SDL_Texture *) ((AtlasRegion *) mesh->getRendererObject())->page->getRendererObject();
verticesCount = mesh->getWorldVerticesLength() >> 1; verticesCount = mesh->getWorldVerticesLength() >> 1;
uvs = &mesh->getUVs(); uvs = &mesh->getUVs();
indices = &mesh->getTriangles(); indices = &mesh->getTriangles();

View File

@ -211,12 +211,12 @@ namespace spine {
} }
if (mesh->super.worldVerticesLength > SPINE_MESH_VERTEX_COUNT_MAX) continue; if (mesh->super.worldVerticesLength > SPINE_MESH_VERTEX_COUNT_MAX) continue;
texture = (Texture *) ((spAtlasRegion *) mesh->rendererObject)->page->rendererObject;
spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, worldVertices, 0, 2); spVertexAttachment_computeWorldVertices(SUPER(mesh), slot, 0, mesh->super.worldVerticesLength, worldVertices, 0, 2);
verticesCount = mesh->super.worldVerticesLength >> 1; verticesCount = mesh->super.worldVerticesLength >> 1;
uvs = mesh->uvs; uvs = mesh->uvs;
indices = mesh->triangles; indices = mesh->triangles;
indicesCount = mesh->trianglesCount; indicesCount = mesh->trianglesCount;
texture = (Texture *) ((spAtlasRegion *) mesh->rendererObject)->page->rendererObject;
} else if (attachment->type == SP_ATTACHMENT_CLIPPING) { } else if (attachment->type == SP_ATTACHMENT_CLIPPING) {
spClippingAttachment *clip = (spClippingAttachment *) slot->attachment; spClippingAttachment *clip = (spClippingAttachment *) slot->attachment;

View File

@ -136,11 +136,11 @@ namespace spine {
} }
worldVertices.setSize(mesh->getWorldVerticesLength(), 0); worldVertices.setSize(mesh->getWorldVerticesLength(), 0);
texture = (Texture *) mesh->getRegion()->rendererObject;
mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices.buffer(), 0, 2); mesh->computeWorldVertices(slot, 0, mesh->getWorldVerticesLength(), worldVertices.buffer(), 0, 2);
uvs = &mesh->getUVs(); uvs = &mesh->getUVs();
indices = &mesh->getTriangles(); indices = &mesh->getTriangles();
indicesCount = mesh->getTriangles().size(); indicesCount = mesh->getTriangles().size();
texture = (Texture *) ((AtlasRegion *) mesh->getRendererObject())->page->getRendererObject();
} else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) { } else if (attachment->getRTTI().isExactly(ClippingAttachment::rtti)) {
ClippingAttachment *clip = (ClippingAttachment *) slot.getAttachment(); ClippingAttachment *clip = (ClippingAttachment *) slot.getAttachment();

View File

@ -30,6 +30,8 @@
import { Utils, Color, Skeleton, RegionAttachment, TextureAtlasRegion, BlendMode, MeshAttachment, Slot } from "@esotericsoftware/spine-core"; import { Utils, Color, Skeleton, RegionAttachment, TextureAtlasRegion, BlendMode, MeshAttachment, Slot } from "@esotericsoftware/spine-core";
import { CanvasTexture } from "./CanvasTexture"; import { CanvasTexture } from "./CanvasTexture";
const worldVertices = Utils.newFloatArray(8);
export class SkeletonRenderer { export class SkeletonRenderer {
static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; static QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
static VERTEX_SIZE = 2 + 2 + 4; static VERTEX_SIZE = 2 + 2 + 4;
@ -65,6 +67,7 @@ export class SkeletonRenderer {
let attachment = slot.getAttachment(); let attachment = slot.getAttachment();
if (!(attachment instanceof RegionAttachment)) continue; if (!(attachment instanceof RegionAttachment)) continue;
attachment.computeWorldVertices(slot, worldVertices, 0, 2);
let region: TextureAtlasRegion = <TextureAtlasRegion>attachment.region; let region: TextureAtlasRegion = <TextureAtlasRegion>attachment.region;
let image: HTMLImageElement = (<CanvasTexture>region.page.texture).getImage() as HTMLImageElement; let image: HTMLImageElement = (<CanvasTexture>region.page.texture).getImage() as HTMLImageElement;

View File

@ -88,6 +88,20 @@ export class RegionAttachment extends Attachment implements HasTextureRegion {
updateRegion (): void { updateRegion (): void {
if (!this.region) throw new Error("Region not set."); if (!this.region) throw new Error("Region not set.");
let region = this.region; let region = this.region;
let uvs = this.uvs;
if (region == null) {
uvs[0] = 0;
uvs[1] = 0;
uvs[2] = 0;
uvs[3] = 1;
uvs[4] = 1;
uvs[5] = 1;
uvs[6] = 1;
uvs[7] = 0;
return;
}
let regionScaleX = this.width / this.region.originalWidth * this.scaleX; let regionScaleX = this.width / this.region.originalWidth * this.scaleX;
let regionScaleY = this.height / this.region.originalHeight * this.scaleY; let regionScaleY = this.height / this.region.originalHeight * this.scaleY;
let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX;
@ -116,16 +130,15 @@ export class RegionAttachment extends Attachment implements HasTextureRegion {
offset[6] = localX2Cos - localYSin; offset[6] = localX2Cos - localYSin;
offset[7] = localYCos + localX2Sin; offset[7] = localYCos + localX2Sin;
let uvs = this.uvs;
if (region.degrees == 90) { if (region.degrees == 90) {
uvs[0] = region.u2;
uvs[1] = region.v2;
uvs[2] = region.u; uvs[2] = region.u;
uvs[3] = region.v2; uvs[3] = region.v2;
uvs[4] = region.u; uvs[4] = region.u;
uvs[5] = region.v; uvs[5] = region.v;
uvs[6] = region.u2; uvs[6] = region.u2;
uvs[7] = region.v; uvs[7] = region.v;
uvs[0] = region.u2;
uvs[1] = region.v2;
} else { } else {
uvs[0] = region.u; uvs[0] = region.u;
uvs[1] = region.v2; uvs[1] = region.v2;

View File

@ -274,8 +274,8 @@ void SSpineWidget::UpdateMesh(int32 LayerId, FSlateWindowElementList &OutDrawEle
if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) { if (attachment->getRTTI().isExactly(RegionAttachment::rtti)) {
RegionAttachment *regionAttachment = (RegionAttachment *) attachment; RegionAttachment *regionAttachment = (RegionAttachment *) attachment;
attachmentColor.set(regionAttachment->getColor()); attachmentColor.set(regionAttachment->getColor());
attachmentAtlasRegion = (AtlasRegion *) regionAttachment->getRendererObject();
regionAttachment->computeWorldVertices(*slot, *attachmentVertices, 0, 2); regionAttachment->computeWorldVertices(*slot, *attachmentVertices, 0, 2);
attachmentAtlasRegion = (AtlasRegion *) regionAttachment->getRendererObject();
attachmentIndices = quadIndices; attachmentIndices = quadIndices;
attachmentUvs = regionAttachment->getUVs().buffer(); attachmentUvs = regionAttachment->getUVs().buffer();
numVertices = 4; numVertices = 4;
@ -283,8 +283,8 @@ void SSpineWidget::UpdateMesh(int32 LayerId, FSlateWindowElementList &OutDrawEle
} else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) { } else if (attachment->getRTTI().isExactly(MeshAttachment::rtti)) {
MeshAttachment *mesh = (MeshAttachment *) attachment; MeshAttachment *mesh = (MeshAttachment *) attachment;
attachmentColor.set(mesh->getColor()); attachmentColor.set(mesh->getColor());
attachmentAtlasRegion = (AtlasRegion *) mesh->getRendererObject();
mesh->computeWorldVertices(*slot, 0, mesh->getWorldVerticesLength(), attachmentVertices->buffer(), 0, 2); mesh->computeWorldVertices(*slot, 0, mesh->getWorldVerticesLength(), attachmentVertices->buffer(), 0, 2);
attachmentAtlasRegion = (AtlasRegion *) mesh->getRendererObject();
attachmentIndices = mesh->getTriangles().buffer(); attachmentIndices = mesh->getTriangles().buffer();
attachmentUvs = mesh->getUVs().buffer(); attachmentUvs = mesh->getUVs().buffer();
numVertices = mesh->getWorldVerticesLength() >> 1; numVertices = mesh->getWorldVerticesLength() >> 1;

View File

@ -236,8 +236,8 @@ void USpineSkeletonRendererComponent::UpdateMesh(Skeleton *Skeleton) {
} }
attachmentColor.set(regionAttachment->getColor()); attachmentColor.set(regionAttachment->getColor());
attachmentAtlasRegion = (AtlasRegion *) regionAttachment->getRendererObject();
regionAttachment->computeWorldVertices(*slot, *attachmentVertices, 0, 2); regionAttachment->computeWorldVertices(*slot, *attachmentVertices, 0, 2);
attachmentAtlasRegion = (AtlasRegion *) regionAttachment->getRendererObject();
attachmentIndices = quadIndices; attachmentIndices = quadIndices;
attachmentUvs = regionAttachment->getUVs().buffer(); attachmentUvs = regionAttachment->getUVs().buffer();
numVertices = 4; numVertices = 4;
@ -252,8 +252,8 @@ void USpineSkeletonRendererComponent::UpdateMesh(Skeleton *Skeleton) {
} }
attachmentColor.set(mesh->getColor()); attachmentColor.set(mesh->getColor());
attachmentAtlasRegion = (AtlasRegion *) mesh->getRendererObject();
mesh->computeWorldVertices(*slot, 0, mesh->getWorldVerticesLength(), attachmentVertices->buffer(), 0, 2); mesh->computeWorldVertices(*slot, 0, mesh->getWorldVerticesLength(), attachmentVertices->buffer(), 0, 2);
attachmentAtlasRegion = (AtlasRegion *) mesh->getRendererObject();
attachmentIndices = mesh->getTriangles().buffer(); attachmentIndices = mesh->getTriangles().buffer();
attachmentUvs = mesh->getUVs().buffer(); attachmentUvs = mesh->getUVs().buffer();
numVertices = mesh->getWorldVerticesLength() >> 1; numVertices = mesh->getWorldVerticesLength() >> 1;