Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Spine 4.0 #1

Open
TobseF opened this issue Feb 18, 2022 · 5 comments
Open

Support Spine 4.0 #1

TobseF opened this issue Feb 18, 2022 · 5 comments
Labels
enhancement New feature or request

Comments

@TobseF
Copy link

TobseF commented Feb 18, 2022

Reading a a json (4.0) or binary Spine 4.0.61 file doesn't work.

Tested with sample code out of KorGE samples/spine.

Duke-Spine.zip
Duke-json.zip
Duke-atlas.zip
duke-clear

Workaround

As a workaround it's possible to export the animation as json with version 3.8. But this has some drawbacks. For example the animation will not support bezier curves and the KorGE plugin won't render a preview animation.

⚡ Error reading skeleton file.

Reading atlas File

korlibs/korge#24: glGetError after glGenVertexArrays
java.lang.RuntimeException: Error reading skeleton file.
	at com.esotericsoftware.spine.SkeletonBinary.readSkeletonData(SkeletonBinary.kt:301)
	at com.esotericsoftware.spine.SkeletonBinary.readSkeletonData(SkeletonBinary.kt:75)
	at com.esotericsoftware.spine.SkeletonBinaryKt.readSkeletonBinary(SkeletonBinary.kt:1070)
	at common.MainCommonKt$main$2.invokeSuspend(mainCommon.kt:17)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at com.soywiz.korgw.GameWindowCoroutineDispatcher.executePending-_rozLdE(GameWindow.kt:128)
	at com.soywiz.korgw.GameWindow.frameUpdate-_rozLdE(GameWindow.kt:441)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4(GameWindow.kt:372)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4$default(GameWindow.kt:365)
	at com.soywiz.korgw.GameWindow.frame(GameWindow.kt:359)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.paintInContext(BaseAwtGameWindow.kt:201)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:113)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:112)
	at com.soywiz.korgw.platform.BaseOpenglContext$DefaultImpls.useContext(BaseOpenglContext.kt:36)
	at com.soywiz.korgw.win32.Win32OpenglContext.useContext(Win32Tools.kt:202)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.framePaint(BaseAwtGameWindow.kt:108)
	at com.soywiz.korgw.awt.AwtGameWindow$frame$1.paint(AwtGameWindow.kt:132)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)


	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
	at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.IllegalStateException: EOF
	at com.esotericsoftware.spine.SkeletonBinary$SkeletonInput.readString(SkeletonBinary.kt:1027)
Caused by: java.lang.IllegalStateException: EOF

	at com.esotericsoftware.spine.SkeletonBinary.readSkeletonData(SkeletonBinary.kt:87)
	... 40 more
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Error reading skeleton file.
	at com.esotericsoftware.spine.SkeletonBinary.readSkeletonData(SkeletonBinary.kt:301)
	at com.esotericsoftware.spine.SkeletonBinary.readSkeletonData(SkeletonBinary.kt:75)
	at com.esotericsoftware.spine.SkeletonBinaryKt.readSkeletonBinary(SkeletonBinary.kt:1070)
	at common.MainCommonKt$main$2.invokeSuspend(mainCommon.kt:17)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at com.soywiz.korgw.GameWindowCoroutineDispatcher.executePending-_rozLdE(GameWindow.kt:128)
	at com.soywiz.korgw.GameWindow.frameUpdate-_rozLdE(GameWindow.kt:441)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4(GameWindow.kt:372)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4$default(GameWindow.kt:365)
	at com.soywiz.korgw.GameWindow.frame(GameWindow.kt:359)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.paintInContext(BaseAwtGameWindow.kt:201)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:113)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:112)
	at com.soywiz.korgw.platform.BaseOpenglContext$DefaultImpls.useContext(BaseOpenglContext.kt:36)
	at com.soywiz.korgw.win32.Win32OpenglContext.useContext(Win32Tools.kt:202)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.framePaint(BaseAwtGameWindow.kt:108)
	at com.soywiz.korgw.awt.AwtGameWindow$frame$1.paint(AwtGameWindow.kt:132)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
	at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.IllegalStateException: EOF
	at com.esotericsoftware.spine.SkeletonBinary$SkeletonInput.readString(SkeletonBinary.kt:1027)
	at com.esotericsoftware.spine.SkeletonBinary.readSkeletonData(SkeletonBinary.kt:87)
	... 40 more

⚡Error reading animation: wink

Reading Json File

swapIntervalEXT: Proxy interface to native function@0x7ffb060b2710 (com.soywiz.korgw.win32.Win32OpenglContext$SwapIntervalCallback)
korlibs/korge#24: glGetError after glGenVertexArrays
java.lang.RuntimeException: Error reading animation: wink
	at com.esotericsoftware.spine.SkeletonJson.readSkeletonData(SkeletonJson.kt:321)
	at com.esotericsoftware.spine.SkeletonJson.readSkeletonData(SkeletonJson.kt:74)
	at com.esotericsoftware.spine.SkeletonJsonKt.readSkeletonJson(SkeletonJson.kt:815)
	at common.MainCommonKt$main$2.invokeSuspend(mainCommon.kt:13)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at com.soywiz.korgw.GameWindowCoroutineDispatcher.executePending-_rozLdE(GameWindow.kt:128)
	at com.soywiz.korgw.GameWindow.frameUpdate-_rozLdE(GameWindow.kt:441)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4(GameWindow.kt:372)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4$default(GameWindow.kt:365)
	at com.soywiz.korgw.GameWindow.frame(GameWindow.kt:359)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.paintInContext(BaseAwtGameWindow.kt:201)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:113)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:112)
	at com.soywiz.korgw.platform.BaseOpenglContext$DefaultImpls.useContext(BaseOpenglContext.kt:36)
	at com.soywiz.korgw.win32.Win32OpenglContext.useContext(Win32Tools.kt:202)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.framePaint(BaseAwtGameWindow.kt:108)
	at com.soywiz.korgw.awt.AwtGameWindow$frame$1.paint(AwtGameWindow.kt:132)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
	at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.IllegalStateException: Value cannot be converted to float: ARRAY
Caused by: java.lang.IllegalStateException: Value cannot be converted to float: ARRAY

	at com.esotericsoftware.spine.utils.SpineJsonValue.asDouble(SpineJsonValue.kt:57)
	at com.esotericsoftware.spine.utils.SpineJsonValue.asFloat(SpineJsonValue.kt:60)
	at com.esotericsoftware.spine.SkeletonJson.readCurve$korge_spine(SkeletonJson.kt:802)
	at com.esotericsoftware.spine.SkeletonJson.readAnimation(SkeletonJson.kt:556)
	at com.esotericsoftware.spine.SkeletonJson.readSkeletonData(SkeletonJson.kt:319)
	... 40 more
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Error reading animation: wink
	at com.esotericsoftware.spine.SkeletonJson.readSkeletonData(SkeletonJson.kt:321)
	at com.esotericsoftware.spine.SkeletonJson.readSkeletonData(SkeletonJson.kt:74)
	at com.esotericsoftware.spine.SkeletonJsonKt.readSkeletonJson(SkeletonJson.kt:815)
	at common.MainCommonKt$main$2.invokeSuspend(mainCommon.kt:13)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at com.soywiz.korgw.GameWindowCoroutineDispatcher.executePending-_rozLdE(GameWindow.kt:128)
	at com.soywiz.korgw.GameWindow.frameUpdate-_rozLdE(GameWindow.kt:441)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4(GameWindow.kt:372)
	at com.soywiz.korgw.GameWindow.frame-eeKXlv4$default(GameWindow.kt:365)
	at com.soywiz.korgw.GameWindow.frame(GameWindow.kt:359)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.paintInContext(BaseAwtGameWindow.kt:201)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:113)
	at com.soywiz.korgw.awt.BaseAwtGameWindow$paintInContextDelegate$1.invoke(BaseAwtGameWindow.kt:112)
	at com.soywiz.korgw.platform.BaseOpenglContext$DefaultImpls.useContext(BaseOpenglContext.kt:36)
	at com.soywiz.korgw.win32.Win32OpenglContext.useContext(Win32Tools.kt:202)
	at com.soywiz.korgw.awt.BaseAwtGameWindow.framePaint(BaseAwtGameWindow.kt:108)
	at com.soywiz.korgw.awt.AwtGameWindow$frame$1.paint(AwtGameWindow.kt:132)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
	at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
	at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.IllegalStateException: Value cannot be converted to float: ARRAY
	at com.esotericsoftware.spine.utils.SpineJsonValue.asDouble(SpineJsonValue.kt:57)
	at com.esotericsoftware.spine.utils.SpineJsonValue.asFloat(SpineJsonValue.kt:60)
	at com.esotericsoftware.spine.SkeletonJson.readCurve$korge_spine(SkeletonJson.kt:802)
	at com.esotericsoftware.spine.SkeletonJson.readAnimation(SkeletonJson.kt:556)
	at com.esotericsoftware.spine.SkeletonJson.readSkeletonData(SkeletonJson.kt:319)
	... 40 more
completed.running=false
GameWindow.close
GameWindowCoroutineDispatcher.close
@soywiz
Copy link
Member

soywiz commented Feb 19, 2022

Just did a diff between the 3.8 and 4.0: https://github.com/korlibs/korge-next/tree/master/korge-spine/original
And there are a lot of changes :)
But let's see if we can catch up

@soywiz soywiz added the enhancement New feature or request label Feb 19, 2022
@TobseF
Copy link
Author

TobseF commented Mar 3, 2022

On the jvm, reading the json in Spine format version 3.8 works in KorGE 2.1.1.3 but is broken with KorGE 2.4.10.
In fromPrimitiveTree it reads the unmapped type of value: DoubleArrayList (name: uvs):

fun fromPrimitiveTree(value: Any?, name: String? = null): SpineJsonValue = when (value) {
            null -> SpineJsonValue(ValueType.NULL)
            is String -> SpineJsonValue(value)
            is Boolean -> SpineJsonValue(value)
            is Number -> SpineJsonValue(value.toDouble(), value.toString())
            is List<*> -> SpineJsonValue(ValueType.ARRAY, value.map { fromPrimitiveTree(it) })
            is Map<*, *> -> SpineJsonValue(ValueType.OBJECT, value.map { fromPrimitiveTree(it.value, it.key as String) })
            else -> TODO()
        }

⚡ NotImplementedError

kotlin.NotImplementedError: An operation is not implemented.
	at com.esotericsoftware.spine.utils.SpineJsonValue$Companion.fromPrimitiveTree(SpineJsonValue.kt:111)

The code hasn't chaged here, so maybe it has something to do with the newer Kotlin version.

@soywiz
Copy link
Member

soywiz commented Mar 3, 2022

Can you provide a sample file I could include in the repo as a regression test and to check it?

@TobseF
Copy link
Author

TobseF commented Mar 3, 2022

Can you use the Duke-json.zip from the first post. And the Duke-Spine.zip contains the Spine project file. Or do you think we should avoid it because of a Duke copyright? If yes, do you have a wish for a character I should put bones on - maybe a good Idea for a new KorGE mascot😉

@TobseF
Copy link
Author

TobseF commented Mar 4, 2022

I found out... the Duke is OpenSource!

. In 2006, Duke was officially “open sourced” under a BSD license. Developers and designers were encouraged to play around with Duke and for the first time had access to Duke’s graphical specifications through a java.net project. Efforts around Duke are now hosted as “Project Duke” at OpenJDK.

https://www.oracle.com/java/duke/
https://wiki.openjdk.java.net/display/duke/Gallery

@soywiz soywiz changed the title Reaing current Spine files is broken Support Spine 4.0 Mar 4, 2022
@soywiz soywiz transferred this issue from korlibs/korge Feb 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

2 participants