11package dev .eatgrapes .live2d .example ;
22
3+ import com .sun .net .httpserver .HttpServer ;
34import dev .eatgrapes .live2d .CubismFramework ;
45import dev .eatgrapes .live2d .CubismUserModel ;
56import org .lwjgl .opengl .GL ;
67import org .lwjgl .stb .STBImage ;
78import org .lwjgl .system .MemoryStack ;
89
910import java .io .InputStream ;
11+ import java .net .InetSocketAddress ;
1012import java .nio .ByteBuffer ;
1113import java .nio .DoubleBuffer ;
1214import java .nio .IntBuffer ;
1517import java .nio .file .StandardCopyOption ;
1618import java .util .HashMap ;
1719import java .util .Map ;
20+ import java .util .concurrent .ConcurrentLinkedQueue ;
1821
1922import static org .lwjgl .glfw .GLFW .*;
2023import static org .lwjgl .opengl .GL11 .*;
@@ -25,17 +28,38 @@ public class Main {
2528 private CubismUserModel model ;
2629 private final Map <String , byte []> motions = new HashMap <>();
2730 private final float [] mvp = new float []{1 ,0 ,0 ,0 , 0 ,1 ,0 ,0 , 0 ,0 ,1 ,0 , 0 ,0 ,0 ,1 };
31+ private final ConcurrentLinkedQueue <Runnable > taskQueue = new ConcurrentLinkedQueue <>();
2832
2933 public void run () throws Exception {
3034 init ();
3135 setup ();
36+ startServer ();
37+ ControlPanel .show ();
3238 loop ();
3339 cleanup ();
3440 }
3541
42+ private void startServer () throws Exception {
43+ HttpServer server = HttpServer .create (new InetSocketAddress (8080 ), 0 );
44+ server .createContext ("/motion" , t -> {
45+ String query = t .getRequestURI ().getQuery ();
46+ String id = query .split ("=" )[1 ];
47+ taskQueue .add (() -> {
48+ try {
49+ model .startMotion (motions .get (id ), 3 , false , null );
50+ } catch (Exception e ) { e .printStackTrace (); }
51+ });
52+ t .sendResponseHeaders (200 , 0 );
53+ t .close ();
54+ });
55+ server .setExecutor (null );
56+ server .start ();
57+ System .out .println ("Control server started on port 8080" );
58+ }
59+
3660 private void init () {
3761 if (!glfwInit ()) throw new RuntimeException ("GLFW failed" );
38- window = glfwCreateWindow (800 , 800 , "Live2D Interaction " , 0 , 0 );
62+ window = glfwCreateWindow (800 , 800 , "Live2D Example " , 0 , 0 );
3963 glfwMakeContextCurrent (window );
4064 GL .createCapabilities ();
4165 glfwSwapInterval (1 );
@@ -52,47 +76,28 @@ private void init() {
5276 if (model != null ) model .setDragging (nx , ny );
5377 }
5478 });
55-
56- glfwSetMouseButtonCallback (window , (win , button , action , mods ) -> {
57- if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS ) {
58- try (MemoryStack s = MemoryStack .stackPush ()) {
59- DoubleBuffer xb = s .mallocDouble (1 ), yb = s .mallocDouble (1 );
60- IntBuffer wb = s .mallocInt (1 ), hb = s .mallocInt (1 );
61- glfwGetCursorPos (win , xb , yb );
62- glfwGetWindowSize (win , wb , hb );
63- float aspect = (float ) wb .get (0 ) / hb .get (0 );
64- float nx = (float ) (xb .get (0 ) / (wb .get (0 ) / 2.0 ) - 1.0 ) * aspect ;
65- float ny = (float ) (1.0 - yb .get (0 ) / (hb .get (0 ) / 2.0 ));
66-
67- if (model .isHit ("HitArea" , nx , ny )) {
68- System .out .println ("Hit Body!" );
69- model .startMotion (motions .get ("m04" ), 3 , false , null );
70- }
71- } catch (Exception e ) { e .printStackTrace (); }
72- }
73- });
7479 }
7580
7681 private void setup () throws Exception {
7782 CubismFramework .startUp ();
7883 CubismFramework .initialize ();
79-
8084 model = new CubismUserModel ();
8185 model .loadModel (load ("/model/Hiyori/Hiyori.moc3" ));
8286 model .loadPose (load ("/model/Hiyori/Hiyori.pose3.json" ));
8387 model .loadPhysics (load ("/model/Hiyori/Hiyori.physics3.json" ));
8488 model .createRenderer ();
85-
8689 model .registerTexture (0 , loadTex ("/model/Hiyori/Hiyori.2048/texture_00.png" ));
8790 model .registerTexture (1 , loadTex ("/model/Hiyori/Hiyori.2048/texture_01.png" ));
88-
91+ motions . put ( "m01" , load ( "/model/Hiyori/motions/Hiyori_m01.motion3.json" ));
8992 motions .put ("m04" , load ("/model/Hiyori/motions/Hiyori_m04.motion3.json" ));
9093 }
9194
9295 private void loop () {
9396 while (!glfwWindowShouldClose (window )) {
97+ Runnable task ;
98+ while ((task = taskQueue .poll ()) != null ) task .run ();
99+
94100 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
95-
96101 try (MemoryStack s = MemoryStack .stackPush ()) {
97102 IntBuffer w = s .mallocInt (1 ), h = s .mallocInt (1 );
98103 glfwGetWindowSize (window , w , h );
@@ -101,7 +106,6 @@ private void loop() {
101106 for (int i = 0 ; i < 16 ; i ++) mvp [i ] = 0 ;
102107 mvp [0 ] = 1.0f / aspect ; mvp [5 ] = 1.0f ; mvp [10 ] = 1.0f ; mvp [15 ] = 1.0f ;
103108 }
104-
105109 model .update (0.016f );
106110 model .draw (mvp );
107111 glfwSwapBuffers (window );
@@ -142,4 +146,4 @@ private int loadTex(String p) throws Exception {
142146 }
143147
144148 public static void main (String [] args ) throws Exception { new Main ().run (); }
145- }
149+ }
0 commit comments