diff --git a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineComponentFactory.java b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineComponentFactory.java index bcefe1a6..4c846b31 100644 --- a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineComponentFactory.java +++ b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineComponentFactory.java @@ -74,7 +74,8 @@ public class SpineComponentFactory extends ComponentFactory { component.skeletonData = component.skeletonJson.readSkeletonData((rm.getSkeletonJSON(vo.animationName))); BoneData rootBone = component.skeletonData.getBones().get(0); - rootBone.setScale(vo.scaleX / projectInfoVO.pixelToWorld, vo.scaleX / projectInfoVO.pixelToWorld); + component.rootBonePosition.set(rootBone.getX(), rootBone.getY()); + rootBone.setScale(1f /projectInfoVO.pixelToWorld, 1f / projectInfoVO.pixelToWorld); component.skeleton = new Skeleton(component.skeletonData); component.worldMultiplier = 1f/projectInfoVO.pixelToWorld; @@ -86,13 +87,6 @@ public class SpineComponentFactory extends ComponentFactory { component.setAnimation(vo.currentAnimationName.isEmpty() ? component.skeletonData.getAnimations().get(0).getName() : vo.currentAnimationName); - TransformComponent transformComponent = ComponentRetriever.get(entity, TransformComponent.class); - transformComponent.scaleX = vo.scaleX; - transformComponent.scaleY = vo.scaleY; - - transformComponent.originX = dimensionsComponent.width / 2; - transformComponent.originY = 0; - entity.add(component); return component; diff --git a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineDrawableLogic.java b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineDrawableLogic.java index e87c0ffe..63477ae8 100644 --- a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineDrawableLogic.java +++ b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineDrawableLogic.java @@ -4,11 +4,16 @@ import com.badlogic.ashley.core.ComponentMapper; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; +import com.badlogic.gdx.math.Affine2; +import com.badlogic.gdx.math.Matrix4; import com.esotericsoftware.spine.SkeletonRenderer; +import games.rednblack.editor.renderer.components.ParentNodeComponent; +import games.rednblack.editor.renderer.components.TransformComponent; import games.rednblack.editor.renderer.systems.render.logic.Drawable; public class SpineDrawableLogic implements Drawable { - + private final ComponentMapper spineObjectComponentMapper = ComponentMapper.getFor(SpineObjectComponent.class); + private final ComponentMapper transformComponentMapper = ComponentMapper.getFor(TransformComponent.class); private final ComponentMapper spineMapper; private final SkeletonRenderer skeletonRenderer; @@ -21,7 +26,52 @@ public class SpineDrawableLogic implements Drawable { public void draw(Batch batch, Entity entity, float parentAlpha) { SpineObjectComponent spineObjectComponent = spineMapper.get(entity); - skeletonRenderer.draw((PolygonSpriteBatch)batch, spineObjectComponent.skeleton); + ParentNodeComponent parentNodeComponent = entity.getComponent(ParentNodeComponent.class); + Entity parentEntity = parentNodeComponent.parentEntity; + TransformComponent parentTransformComponent = transformComponentMapper.get(parentEntity); + + if (parentTransformComponent.scaleX == 1 && parentTransformComponent.scaleY == 1 && parentTransformComponent.rotation == 0) { + computeTransform(entity); + applyTransform(entity, batch); + skeletonRenderer.draw((PolygonSpriteBatch)batch, spineObjectComponent.skeleton); + resetTransform(entity, batch); + } else { + skeletonRenderer.draw((PolygonSpriteBatch)batch, spineObjectComponent.skeleton); + } //TODO parent alpha thing } + + protected Matrix4 computeTransform (Entity rootEntity) { + SpineObjectComponent spineObjectComponent = spineObjectComponentMapper.get(rootEntity); + TransformComponent curTransform = transformComponentMapper.get(rootEntity); + + Affine2 worldTransform = spineObjectComponent.worldTransform; + + float originX = curTransform.originX; + float originY = curTransform.originY; + float x = curTransform.x; + float y = curTransform.y; + float rotation = curTransform.rotation; + float scaleX = curTransform.scaleX; + float scaleY = curTransform.scaleY; + + worldTransform.setToTrnRotScl(x + originX , y + originY, rotation, scaleX, scaleY); + if (originX != 0 || originY != 0) worldTransform.translate(-originX, -originY); + worldTransform.translate(-spineObjectComponent.minX, -spineObjectComponent.minY); + + spineObjectComponent.computedTransform.set(worldTransform); + + return spineObjectComponent.computedTransform; + } + + protected void applyTransform (Entity rootEntity, Batch batch) { + SpineObjectComponent spineObjectComponent = spineObjectComponentMapper.get(rootEntity); + spineObjectComponent.oldTransform.set(batch.getTransformMatrix()); + batch.setTransformMatrix(spineObjectComponent.computedTransform); + } + + protected void resetTransform (Entity rootEntity, Batch batch) { + SpineObjectComponent spineObjectComponent = spineObjectComponentMapper.get(rootEntity); + batch.setTransformMatrix(spineObjectComponent.oldTransform); + } } \ No newline at end of file diff --git a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineObjectComponent.java b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineObjectComponent.java index a38d434b..89d56c68 100644 --- a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineObjectComponent.java +++ b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineObjectComponent.java @@ -2,6 +2,7 @@ package games.rednblack.h2d.extention.spine; import com.badlogic.gdx.math.Affine2; import com.badlogic.gdx.math.Matrix4; +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.FloatArray; import com.esotericsoftware.spine.*; @@ -19,6 +20,7 @@ public class SpineObjectComponent implements BaseComponent { public float minX; public float minY; public float worldMultiplier; + public Vector2 rootBonePosition = new Vector2(); private final FloatArray temp = new FloatArray(); public final Affine2 worldTransform = new Affine2(); public final Matrix4 computedTransform = new Matrix4(); diff --git a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineSystem.java b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineSystem.java index 9eb5aaec..c45311a4 100644 --- a/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineSystem.java +++ b/h2d-libgdx-spine-extension/src/main/java/games/rednblack/h2d/extention/spine/SpineSystem.java @@ -4,7 +4,6 @@ import com.badlogic.ashley.core.ComponentMapper; import com.badlogic.ashley.core.Entity; import com.badlogic.ashley.core.Family; import com.badlogic.ashley.systems.IteratingSystem; -import com.badlogic.gdx.math.Vector2; import com.esotericsoftware.spine.Bone; import games.rednblack.editor.renderer.components.DimensionsComponent; import games.rednblack.editor.renderer.components.ParentNodeComponent; @@ -30,35 +29,18 @@ public class SpineSystem extends IteratingSystem { ParentNodeComponent parentNodeComponent = entity.getComponent(ParentNodeComponent.class); Entity parentEntity = parentNodeComponent.parentEntity; TransformComponent parentTransformComponent = transformComponentMapper.get(parentEntity); - float offsetX = 0; - float offsetY = 0; - - if (parentTransformComponent.scaleX == 1 && parentTransformComponent.scaleY == 1 && parentTransformComponent.rotation == 0) { - offsetX = parentTransformComponent.x; - offsetY = parentTransformComponent.y; - - while (true) { - parentNodeComponent = parentEntity.getComponent(ParentNodeComponent.class); - if (parentNodeComponent == null) { - break; - } - - parentEntity = parentNodeComponent.parentEntity; - if (parentEntity == null) { - break; - } - - parentTransformComponent = transformComponentMapper.get(parentEntity); - offsetX += parentTransformComponent.x; - offsetY += parentTransformComponent.y; - } - } Bone rootBone = spineObjectComponent.skeleton.getRootBone(); - rootBone.setScale(curTransform.scaleX * spineObjectComponent.worldMultiplier, curTransform.scaleY * spineObjectComponent.worldMultiplier); - rootBone.setRotation(curTransform.rotation); - rootBone.setPosition(curTransform.x + dimensionsComponent.width / 2 + offsetX, curTransform.y + offsetY); + if (parentTransformComponent.scaleX == 1 && parentTransformComponent.scaleY == 1 && parentTransformComponent.rotation == 0) { + rootBone.setScale(spineObjectComponent.worldMultiplier, spineObjectComponent.worldMultiplier); + rootBone.setRotation(0); + rootBone.setPosition(spineObjectComponent.rootBonePosition.x, spineObjectComponent.rootBonePosition.y); + } else { + rootBone.setScale(curTransform.scaleX * spineObjectComponent.worldMultiplier, curTransform.scaleY * spineObjectComponent.worldMultiplier); + rootBone.setRotation(curTransform.rotation); + rootBone.setPosition(curTransform.x + dimensionsComponent.width / 2, curTransform.y); + } spineObjectComponent.skeleton.updateWorldTransform(); // spineObjectComponent.state.update(deltaTime); // Update the animation time.