mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-09 08:38:43 +08:00
Bounding boxes for spine-c and spine-sfml.
This commit is contained in:
parent
76778031ed
commit
72339ba824
@ -45,8 +45,8 @@ extern "C" {
|
||||
typedef struct BoundingBoxAttachment BoundingBoxAttachment;
|
||||
struct BoundingBoxAttachment {
|
||||
Attachment super;
|
||||
float* vertices;
|
||||
int verticesCount;
|
||||
float* vertices;
|
||||
};
|
||||
|
||||
BoundingBoxAttachment* BoundingBoxAttachment_create (const char* name);
|
||||
|
||||
@ -63,7 +63,7 @@ struct RegionAttachment {
|
||||
RegionAttachment* RegionAttachment_create (const char* name);
|
||||
void RegionAttachment_setUVs (RegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate);
|
||||
void RegionAttachment_updateOffset (RegionAttachment* self);
|
||||
void RegionAttachment_computeVertices (RegionAttachment* self, float x, float y, Bone* bone, float* vertices);
|
||||
void RegionAttachment_computeWorldVertices (RegionAttachment* self, float x, float y, Bone* bone, float* vertices);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
94
spine-c/include/spine/SkeletonBounds.h
Normal file
94
spine-c/include/spine/SkeletonBounds.h
Normal file
@ -0,0 +1,94 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtime Software License - Version 1.0
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms in whole or in part, with
|
||||
* or without modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. A Spine Single User License or Spine Professional License must be
|
||||
* purchased from Esoteric Software and the license must remain valid:
|
||||
* http://esotericsoftware.com/
|
||||
* 2. Redistributions of source code must retain this license, which is the
|
||||
* above copyright notice, this declaration of conditions and the following
|
||||
* disclaimer.
|
||||
* 3. Redistributions in binary form must reproduce this license, which is the
|
||||
* above copyright notice, this declaration of conditions and the following
|
||||
* disclaimer, in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SPINE_SKELETONBOUNDS_H_
|
||||
#define SPINE_SKELETONBOUNDS_H_
|
||||
|
||||
#include <spine/BoundingBoxAttachment.h>
|
||||
#include <spine/Skeleton.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
float* const vertices;
|
||||
int count;
|
||||
int capacity;
|
||||
} Polygon;
|
||||
|
||||
Polygon* Polygon_create (int capacity);
|
||||
void Polygon_dispose (Polygon* self);
|
||||
|
||||
int/*bool*/Polygon_containsPoint (Polygon* polygon, float x, float y);
|
||||
int/*bool*/Polygon_intersectsSegment (Polygon* polygon, float x1, float y1, float x2, float y2);
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
BoundingBoxAttachment** boundingBoxes;
|
||||
Polygon** polygons;
|
||||
|
||||
float minX, minY, maxX, maxY;
|
||||
} SkeletonBounds;
|
||||
|
||||
SkeletonBounds* SkeletonBounds_create ();
|
||||
void SkeletonBounds_dispose (SkeletonBounds* self);
|
||||
void SkeletonBounds_update (SkeletonBounds* self, Skeleton* skeleton, int/*bool*/updateAabb);
|
||||
|
||||
/** Returns true if the axis aligned bounding box contains the point. */
|
||||
int/*bool*/SkeletonBounds_aabbContainsPoint (SkeletonBounds* self, float x, float y);
|
||||
|
||||
/** Returns true if the axis aligned bounding box intersects the line segment. */
|
||||
int/*bool*/SkeletonBounds_aabbIntersectsSegment (SkeletonBounds* self, float x1, float y1, float x2, float y2);
|
||||
|
||||
/** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
|
||||
int/*bool*/SkeletonBounds_aabbIntersectsSkeleton (SkeletonBounds* self, SkeletonBounds* bounds);
|
||||
|
||||
/** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
|
||||
* efficient to only call this method if SkeletonBounds_aabbContainsPoint returns true. */
|
||||
BoundingBoxAttachment* SkeletonBounds_containsPoint (SkeletonBounds* self, float x, float y);
|
||||
|
||||
/** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
|
||||
* more efficient to only call this method if SkeletonBounds_aabbIntersectsSegment returns true. */
|
||||
BoundingBoxAttachment* SkeletonBounds_intersectsSegment (SkeletonBounds* self, float x1, float y1, float x2, float y2);
|
||||
|
||||
/** Returns the polygon for the specified bounding box, or null. */
|
||||
Polygon* SkeletonBounds_getPolygon (SkeletonBounds* self, BoundingBoxAttachment* boundingBox);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SPINE_SKELETONBOUNDS_H_ */
|
||||
@ -44,7 +44,9 @@
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BoneData.h>
|
||||
#include <spine/RegionAttachment.h>
|
||||
#include <spine/BoundingBoxAttachment.h>
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/SkeletonBounds.h>
|
||||
#include <spine/SkeletonData.h>
|
||||
#include <spine/SkeletonJson.h>
|
||||
#include <spine/Skin.h>
|
||||
|
||||
@ -80,9 +80,11 @@
|
||||
<ClInclude Include="include\spine\AttachmentLoader.h" />
|
||||
<ClInclude Include="include\spine\Bone.h" />
|
||||
<ClInclude Include="include\spine\BoneData.h" />
|
||||
<ClInclude Include="include\spine\BoundingBoxAttachment.h" />
|
||||
<ClInclude Include="include\spine\extension.h" />
|
||||
<ClInclude Include="include\spine\RegionAttachment.h" />
|
||||
<ClInclude Include="include\spine\Skeleton.h" />
|
||||
<ClInclude Include="include\spine\SkeletonBounds.h" />
|
||||
<ClInclude Include="include\spine\SkeletonData.h" />
|
||||
<ClInclude Include="include\spine\SkeletonJson.h" />
|
||||
<ClInclude Include="include\spine\Skin.h" />
|
||||
@ -101,10 +103,12 @@
|
||||
<ClCompile Include="src\spine\AttachmentLoader.c" />
|
||||
<ClCompile Include="src\spine\Bone.c" />
|
||||
<ClCompile Include="src\spine\BoneData.c" />
|
||||
<ClCompile Include="src\spine\BoundingBoxAttachment.c" />
|
||||
<ClCompile Include="src\spine\extension.c" />
|
||||
<ClCompile Include="src\spine\Json.c" />
|
||||
<ClCompile Include="src\spine\RegionAttachment.c" />
|
||||
<ClCompile Include="src\spine\Skeleton.c" />
|
||||
<ClCompile Include="src\spine\SkeletonBounds.c" />
|
||||
<ClCompile Include="src\spine\SkeletonData.c" />
|
||||
<ClCompile Include="src\spine\SkeletonJson.c" />
|
||||
<ClCompile Include="src\spine\Skin.c" />
|
||||
|
||||
@ -72,6 +72,12 @@
|
||||
<ClInclude Include="src\spine\Json.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\spine\BoundingBoxAttachment.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\spine\SkeletonBounds.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\spine\Animation.c">
|
||||
@ -128,5 +134,11 @@
|
||||
<ClCompile Include="src\spine\SlotData.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\spine\BoundingBoxAttachment.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\spine\SkeletonBounds.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -41,7 +41,7 @@ BoundingBoxAttachment* BoundingBoxAttachment_create (const char* name) {
|
||||
return self;
|
||||
}
|
||||
|
||||
void BoundingBoxAttachment_computeVertices (BoundingBoxAttachment* self, float x, float y, Bone* bone, float* worldVertices) {
|
||||
void BoundingBoxAttachment_computeWorldVertices (BoundingBoxAttachment* self, float x, float y, Bone* bone, float* worldVertices) {
|
||||
int i;
|
||||
float px, py;
|
||||
float* vertices = self->vertices;
|
||||
|
||||
@ -98,7 +98,7 @@ void RegionAttachment_updateOffset (RegionAttachment* self) {
|
||||
self->offset[VERTEX_Y4] = localYCos + localX2Sin;
|
||||
}
|
||||
|
||||
void RegionAttachment_computeVertices (RegionAttachment* self, float x, float y, Bone* bone, float* vertices) {
|
||||
void RegionAttachment_computeWorldVertices (RegionAttachment* self, float x, float y, Bone* bone, float* vertices) {
|
||||
float* offset = self->offset;
|
||||
x += bone->worldX;
|
||||
y += bone->worldY;
|
||||
|
||||
209
spine-c/src/spine/SkeletonBounds.c
Normal file
209
spine-c/src/spine/SkeletonBounds.c
Normal file
@ -0,0 +1,209 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtime Software License - Version 1.0
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms in whole or in part, with
|
||||
* or without modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. A Spine Single User License or Spine Professional License must be
|
||||
* purchased from Esoteric Software and the license must remain valid:
|
||||
* http://esotericsoftware.com/
|
||||
* 2. Redistributions of source code must retain this license, which is the
|
||||
* above copyright notice, this declaration of conditions and the following
|
||||
* disclaimer.
|
||||
* 3. Redistributions in binary form must reproduce this license, which is the
|
||||
* above copyright notice, this declaration of conditions and the following
|
||||
* disclaimer, in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <spine/SkeletonBounds.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
Polygon* Polygon_create (int capacity) {
|
||||
Polygon* self = NEW(Polygon);
|
||||
self->capacity = capacity;
|
||||
CONST_CAST(float*, self->vertices) = MALLOC(float, capacity);
|
||||
return self;
|
||||
}
|
||||
|
||||
void Polygon_dispose (Polygon* self) {
|
||||
FREE(self->vertices);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
int/*bool*/Polygon_containsPoint (Polygon* self, float x, float y) {
|
||||
int prevIndex = self->count - 2;
|
||||
int inside = 0;
|
||||
int i = 0;
|
||||
for (; i < self->count; i += 2) {
|
||||
float vertexY = self->vertices[i + 1];
|
||||
float prevY = self->vertices[prevIndex + 1];
|
||||
if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
|
||||
float vertexX = self->vertices[i];
|
||||
if (vertexX + (y - vertexY) / (prevY - vertexY) * (self->vertices[prevIndex] - vertexX) < x) inside = !inside;
|
||||
}
|
||||
prevIndex = i;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
int/*bool*/Polygon_intersectsSegment (Polygon* self, float x1, float y1, float x2, float y2) {
|
||||
float width12 = x1 - x2, height12 = y1 - y2;
|
||||
float det1 = x1 * y2 - y1 * x2;
|
||||
float x3 = self->vertices[self->count - 2], y3 = self->vertices[self->count - 1];
|
||||
int i = 0;
|
||||
for (; i < self->count; i += 2) {
|
||||
float x4 = self->vertices[i], y4 = self->vertices[i + 1];
|
||||
float det2 = x3 * y4 - y3 * x4;
|
||||
float width34 = x3 - x4, height34 = y3 - y4;
|
||||
float det3 = width12 * height34 - height12 * width34;
|
||||
float x = (det1 * width34 - width12 * det2) / det3;
|
||||
if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
|
||||
float y = (det1 * height34 - height12 * det2) / det3;
|
||||
if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return 1;
|
||||
}
|
||||
x3 = x4;
|
||||
y3 = y4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
typedef struct {
|
||||
SkeletonBounds super;
|
||||
int capacity;
|
||||
} _Internal;
|
||||
|
||||
SkeletonBounds* SkeletonBounds_create () {
|
||||
return SUPER(NEW(_Internal));
|
||||
}
|
||||
|
||||
void SkeletonBounds_dispose (SkeletonBounds* self) {
|
||||
int i = 0;
|
||||
for (; i < SUB_CAST(_Internal, self)->capacity; ++i)
|
||||
Polygon_dispose(self->polygons[i]);
|
||||
FREE(self->polygons);
|
||||
FREE(self->boundingBoxes);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
void SkeletonBounds_update (SkeletonBounds* self, Skeleton* skeleton, int/*bool*/updateAabb) {
|
||||
int i;
|
||||
|
||||
_Internal* internal = SUB_CAST(_Internal, self);
|
||||
if (internal->capacity < skeleton->slotCount) {
|
||||
Polygon** newPolygons;
|
||||
|
||||
FREE(self->boundingBoxes);
|
||||
self->boundingBoxes = MALLOC(BoundingBoxAttachment*, skeleton->slotCount);
|
||||
|
||||
newPolygons = CALLOC(Polygon*, skeleton->slotCount);
|
||||
memcpy(newPolygons, self->polygons, internal->capacity);
|
||||
FREE(self->polygons);
|
||||
self->polygons = newPolygons;
|
||||
|
||||
internal->capacity = skeleton->slotCount;
|
||||
}
|
||||
|
||||
self->minX = (float)INT_MAX;
|
||||
self->minY = (float)INT_MIN;
|
||||
self->maxX = (float)INT_MAX;
|
||||
self->maxY = (float)INT_MIN;
|
||||
|
||||
self->count = 0;
|
||||
for (i = 0; i < skeleton->slotCount; ++i) {
|
||||
Polygon* polygon;
|
||||
BoundingBoxAttachment* boundingBox;
|
||||
|
||||
Slot* slot = skeleton->slots[i];
|
||||
Attachment* attachment = slot->attachment;
|
||||
if (!attachment || attachment->type != ATTACHMENT_BOUNDING_BOX) continue;
|
||||
boundingBox = (BoundingBoxAttachment*)attachment;
|
||||
self->boundingBoxes[self->count] = boundingBox;
|
||||
|
||||
polygon = self->polygons[self->count];
|
||||
if (!polygon || polygon->capacity < boundingBox->verticesCount) {
|
||||
if (polygon) Polygon_dispose(polygon);
|
||||
self->polygons[self->count] = polygon = Polygon_create(boundingBox->verticesCount);
|
||||
}
|
||||
polygon->count = boundingBox->verticesCount;
|
||||
BoundingBoxAttachment_computeWorldVertices(boundingBox, skeleton->x, skeleton->y, slot->bone, polygon->vertices);
|
||||
|
||||
if (updateAabb) {
|
||||
int ii = 0;
|
||||
for (; ii < polygon->count; ii += 2) {
|
||||
float x = polygon->vertices[ii];
|
||||
float y = polygon->vertices[ii + 1];
|
||||
if (x < self->minX) self->minX = x;
|
||||
if (y < self->minY) self->minY = y;
|
||||
if (x > self->maxX) self->maxX = x;
|
||||
if (y > self->maxY) self->maxY = y;
|
||||
}
|
||||
}
|
||||
|
||||
++self->count;
|
||||
}
|
||||
}
|
||||
|
||||
int/*bool*/SkeletonBounds_aabbContainsPoint (SkeletonBounds* self, float x, float y) {
|
||||
return x >= self->minX && x <= self->maxX && y >= self->minY && y <= self->maxY;
|
||||
}
|
||||
|
||||
int/*bool*/SkeletonBounds_aabbIntersectsSegment (SkeletonBounds* self, float x1, float y1, float x2, float y2) {
|
||||
float m, x, y;
|
||||
if ((x1 <= self->minX && x2 <= self->minX) || (y1 <= self->minY && y2 <= self->minY) || (x1 >= self->maxX && x2 >= self->maxX)
|
||||
|| (y1 >= self->maxY && y2 >= self->maxY)) return 0;
|
||||
m = (y2 - y1) / (x2 - x1);
|
||||
y = m * (self->minX - x1) + y1;
|
||||
if (y > self->minY && y < self->maxY) return 1;
|
||||
y = m * (self->maxX - x1) + y1;
|
||||
if (y > self->minY && y < self->maxY) return 1;
|
||||
x = (self->minY - y1) / m + x1;
|
||||
if (x > self->minX && x < self->maxX) return 1;
|
||||
x = (self->maxY - y1) / m + x1;
|
||||
if (x > self->minX && x < self->maxX) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int/*bool*/SkeletonBounds_aabbIntersectsSkeleton (SkeletonBounds* self, SkeletonBounds* bounds) {
|
||||
return self->minX < bounds->maxX && self->maxX > bounds->minX && self->minY < bounds->maxY && self->maxY > bounds->minY;
|
||||
}
|
||||
|
||||
BoundingBoxAttachment* SkeletonBounds_containsPoint (SkeletonBounds* self, float x, float y) {
|
||||
int i = 0;
|
||||
for (; i < self->count; ++i)
|
||||
if (Polygon_containsPoint(self->polygons[i], x, y)) return self->boundingBoxes[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
BoundingBoxAttachment* SkeletonBounds_intersectsSegment (SkeletonBounds* self, float x1, float y1, float x2, float y2) {
|
||||
int i = 0;
|
||||
for (; i < self->count; ++i)
|
||||
if (Polygon_intersectsSegment(self->polygons[i], x1, y1, x2, y2)) return self->boundingBoxes[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
Polygon* SkeletonBounds_getPolygon (SkeletonBounds* self, BoundingBoxAttachment* boundingBox) {
|
||||
int i = 0;
|
||||
for (; i < self->count; ++i)
|
||||
if (self->boundingBoxes[i] == boundingBox) return self->polygons[i];
|
||||
return 0;
|
||||
}
|
||||
@ -411,7 +411,9 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* jso
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attachment->type == ATTACHMENT_REGION || attachment->type == ATTACHMENT_REGION_SEQUENCE) {
|
||||
switch (attachment->type) {
|
||||
case ATTACHMENT_REGION:
|
||||
case ATTACHMENT_REGION_SEQUENCE: {
|
||||
RegionAttachment* regionAttachment = (RegionAttachment*)attachment;
|
||||
regionAttachment->x = Json_getFloat(attachmentMap, "x", 0) * self->scale;
|
||||
regionAttachment->y = Json_getFloat(attachmentMap, "y", 0) * self->scale;
|
||||
@ -421,6 +423,19 @@ SkeletonData* SkeletonJson_readSkeletonData (SkeletonJson* self, const char* jso
|
||||
regionAttachment->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
||||
regionAttachment->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
|
||||
RegionAttachment_updateOffset(regionAttachment);
|
||||
break;
|
||||
}
|
||||
case ATTACHMENT_BOUNDING_BOX: {
|
||||
BoundingBoxAttachment* box = (BoundingBoxAttachment*)attachment;
|
||||
Json* verticesArray = Json_getItem(attachmentMap, "vertices");
|
||||
Json* vertex;
|
||||
int i = 0;
|
||||
box->verticesCount = verticesArray->size;
|
||||
box->vertices = MALLOC(float, verticesArray->size);
|
||||
for (vertex = verticesArray->child; vertex; vertex = vertex->next, ++i)
|
||||
box->vertices[i] = vertex->valueFloat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Skin_addAttachment(skin, slotIndex, skinAttachmentName, attachment);
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <string.h>
|
||||
#include <spine/spine-sfml.h>
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Window/Mouse.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace spine;
|
||||
@ -50,6 +51,7 @@ void spineboy () {
|
||||
exit(0);
|
||||
}
|
||||
SkeletonJson_dispose(json);
|
||||
SkeletonBounds* bounds = SkeletonBounds_create();
|
||||
|
||||
// Configure mixing.
|
||||
AnimationStateData* stateData = AnimationStateData_create(skeletonData);
|
||||
@ -68,6 +70,8 @@ void spineboy () {
|
||||
skeleton->root->y = 420;
|
||||
Skeleton_updateWorldTransform(skeleton);
|
||||
|
||||
Slot* headSlot = Skeleton_findSlot(skeleton, "head");
|
||||
|
||||
if (true) {
|
||||
AnimationState_setAnimationByName(drawable->state, "drawOrder", true);
|
||||
} else {
|
||||
@ -87,11 +91,15 @@ void spineboy () {
|
||||
float delta = deltaClock.getElapsedTime().asSeconds();
|
||||
deltaClock.restart();
|
||||
|
||||
/*if (drawable->state->loop) {
|
||||
if (drawable->state->time > 2) AnimationState_setAnimationByName(drawable->state, "jump", false);
|
||||
} else {
|
||||
if (drawable->state->time > 1) AnimationState_setAnimationByName(drawable->state, "walk", true);
|
||||
}*/
|
||||
SkeletonBounds_update(bounds, skeleton, true);
|
||||
sf::Vector2i position = sf::Mouse::getPosition(window);
|
||||
if (SkeletonBounds_containsPoint(bounds, position.x, position.y)) {
|
||||
headSlot->g = 0;
|
||||
headSlot->b = 0;
|
||||
} else {
|
||||
headSlot->g = 1;
|
||||
headSlot->b = 1;
|
||||
}
|
||||
|
||||
drawable->update(delta);
|
||||
|
||||
@ -105,7 +113,7 @@ void spineboy () {
|
||||
}
|
||||
|
||||
void goblins () {
|
||||
// Load atlas, skeleton, and animations.
|
||||
// Load atlas, skeleton, and animations.
|
||||
Atlas* atlas = Atlas_readAtlasFile("../data/goblins.atlas");
|
||||
SkeletonJson* json = SkeletonJson_create(atlas);
|
||||
json->scale = 2;
|
||||
|
||||
@ -89,7 +89,7 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
vertexArray->clear();
|
||||
states.blendMode = BlendAlpha;
|
||||
|
||||
float vertexPositions[8];
|
||||
float worldVertices[8];
|
||||
for (int i = 0; i < skeleton->slotCount; ++i) {
|
||||
Slot* slot = skeleton->drawOrder[i];
|
||||
Attachment* attachment = slot->attachment;
|
||||
@ -103,7 +103,7 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
states.blendMode = blend;
|
||||
}
|
||||
|
||||
RegionAttachment_computeVertices(regionAttachment, slot->skeleton->x, slot->skeleton->y, slot->bone, vertexPositions);
|
||||
RegionAttachment_computeWorldVertices(regionAttachment, slot->skeleton->x, slot->skeleton->y, slot->bone, worldVertices);
|
||||
|
||||
Uint8 r = skeleton->r * slot->r * 255;
|
||||
Uint8 g = skeleton->g * slot->g * 255;
|
||||
@ -128,14 +128,14 @@ void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
|
||||
vertices[3].color.b = b;
|
||||
vertices[3].color.a = a;
|
||||
|
||||
vertices[0].position.x = vertexPositions[VERTEX_X1];
|
||||
vertices[0].position.y = vertexPositions[VERTEX_Y1];
|
||||
vertices[1].position.x = vertexPositions[VERTEX_X2];
|
||||
vertices[1].position.y = vertexPositions[VERTEX_Y2];
|
||||
vertices[2].position.x = vertexPositions[VERTEX_X3];
|
||||
vertices[2].position.y = vertexPositions[VERTEX_Y3];
|
||||
vertices[3].position.x = vertexPositions[VERTEX_X4];
|
||||
vertices[3].position.y = vertexPositions[VERTEX_Y4];
|
||||
vertices[0].position.x = worldVertices[VERTEX_X1];
|
||||
vertices[0].position.y = worldVertices[VERTEX_Y1];
|
||||
vertices[1].position.x = worldVertices[VERTEX_X2];
|
||||
vertices[1].position.y = worldVertices[VERTEX_Y2];
|
||||
vertices[2].position.x = worldVertices[VERTEX_X3];
|
||||
vertices[2].position.y = worldVertices[VERTEX_Y3];
|
||||
vertices[3].position.x = worldVertices[VERTEX_X4];
|
||||
vertices[3].position.y = worldVertices[VERTEX_Y4];
|
||||
|
||||
// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
|
||||
states.texture = (Texture*)((AtlasRegion*)regionAttachment->rendererObject)->page->rendererObject;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user