Skip to content

Commit eb05cb4

Browse files
committed
docs: Add initial Wiki documentation
1 parent f5ae634 commit eb05cb4

7 files changed

Lines changed: 311 additions & 0 deletions

wiki_docs/Getting-Started.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Getting Started
2+
3+
This guide will help you integrate Live2D-JavaBinding into your project.
4+
5+
## Prerequisites
6+
7+
1. **Java 9 or higher**: The library uses JPMS (Java Platform Module System) and APIs introduced in Java 9.
8+
2. **OpenGL Context**: You need a library to create a window and an OpenGL context. We recommend **LWJGL 3**, but any library that provides access to OpenGL bindings will work.
9+
10+
## Installation
11+
12+
Since this library is not hosted on a public Maven repository, you must download the latest release and install it manually.
13+
14+
### 1. Download Release
15+
Go to the [GitHub Releases](../../releases) page and download:
16+
* `live2d-shared.jar`
17+
* `live2d-native-[platform].jar` (e.g., `live2d-native-windows-x64.jar`)
18+
19+
### 2. Manual Installation
20+
You can install them into your local Maven repository:
21+
22+
```bash
23+
mvn install:install-file -Dfile=live2d-shared.jar -DgroupId=com.example -DartifactId=live2d-shared -Dversion=1.0.0 -Dpackaging=jar
24+
mvn install:install-file -Dfile=live2d-native-windows-x64.jar -DgroupId=com.example -DartifactId=live2d-native -Dversion=1.0.0 -Dpackaging=jar -Dclassifier=windows-x64
25+
```
26+
27+
### 3. Build Configuration
28+
29+
#### Maven
30+
```xml
31+
<dependencies>
32+
<!-- The Core Java API -->
33+
<dependency>
34+
<groupId>com.example</groupId>
35+
<artifactId>live2d-shared</artifactId>
36+
<version>1.0.0</version>
37+
</dependency>
38+
39+
<!-- Native Implementation -->
40+
<dependency>
41+
<groupId>com.example</groupId>
42+
<artifactId>live2d-native</artifactId>
43+
<version>1.0.0</version>
44+
<classifier>windows-x64</classifier> <!-- Change classifier as needed -->
45+
</dependency>
46+
</dependencies>
47+
```
48+
49+
#### Gradle
50+
For Gradle, the simplest way is to put the JARs directly into your project:
51+
52+
1. Create a `libs` folder in your project root.
53+
2. Copy the downloaded JARs into it.
54+
3. Add dependencies in `build.gradle`:
55+
56+
```groovy
57+
dependencies {
58+
implementation files('libs/live2d-shared.jar')
59+
implementation files('libs/live2d-native-windows-x64.jar') // Change for your platform
60+
}
61+
```
62+
63+
## Your First Steps
64+
65+
The general flow of a Live2D application is:
66+
67+
1. **Initialize**: Call `CubismFramework.startUp()`.
68+
2. **Load**: Load your model bytes and textures.
69+
3. **Loop**: In your render loop, call `model.update()` and `model.draw()`.
70+
4. **Dispose**: Clean up when done.
71+
72+
Check out the specific sections in the sidebar to learn how to implement each step!

wiki_docs/Home.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Welcome to the Live2D-JavaBinding Wiki
2+
3+
This project provides a high-performance, native Java binding for the **Live2D Cubism SDK**. It allows you to load, render, and interact with Live2D models directly in your Java applications using OpenGL.
4+
5+
## Philosophy
6+
7+
The library is designed to be **unopinionated** about your windowing system. Whether you use **LWJGL**, **JOGL**, or even **JavaFX** (with an OpenGL bridge), this binding provides the raw tools to render the model. We handle the JNI complexity; you handle the context.
8+
9+
## Navigation
10+
11+
* **[Getting Started](Getting-Started)**: Installation and your first model.
12+
* **[Lifecycle Management](Lifecycle-Management)**: Starting up and shutting down the native core safely.
13+
* **[Loading Assets](Loading-Assets)**: How to load `.moc3` files, textures, physics, and poses.
14+
* **[Rendering Loop](Rendering-Loop)**: The essential `update` and `draw` cycle.
15+
* **[Motion & Expressions](Motion-and-Expressions)**: Bringing the model to life with animations.
16+
* **[Interaction & Parameters](Interaction-and-Parameters)**: Hit testing, eye tracking, and manual parameter control.
17+
18+
## Status
19+
20+
This project is currently **Work in Progress**. APIs may change slightly as we reach feature parity with the official C++ SDK.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Interaction & Parameters
2+
3+
Interactive apps require the model to react to the user.
4+
5+
## Mouse Dragging (Look At)
6+
7+
You can make the character look at the mouse cursor.
8+
9+
```java
10+
// Coordinates should be normalized:
11+
// X: -1.0 (Left) to 1.0 (Right)
12+
// Y: -1.0 (Bottom) to 1.0 (Top)
13+
model.setDragging(mouseX, mouseY);
14+
```
15+
16+
Call this every time the mouse moves. The model uses this to update standard parameters like `ParamAngleX`, `ParamAngleY`, `ParamEyeBallX`, etc.
17+
18+
## Hit Testing
19+
20+
Detect if the user clicked a specific part of the model (like the head or chest).
21+
22+
```java
23+
// The ID usually comes from the .model3.json "HitAreas" section
24+
String hitAreaId = "Head";
25+
26+
if (model.isHit(hitAreaId, mouseX, mouseY)) {
27+
System.out.println("Headpats received!");
28+
model.startExpression("Blush");
29+
}
30+
```
31+
32+
## Manual Parameter Control
33+
34+
Sometimes you want direct control (e.g., syncing mouth open with microphone volume).
35+
36+
```java
37+
// 1. Set a value (0.0 to 1.0, or -30 to 30 depending on the parameter)
38+
model.setParameterValue("ParamMouthOpenY", 1.0f);
39+
40+
// 2. Get the current value
41+
float currentMouth = model.getParameterValue("ParamMouthOpenY");
42+
```
43+
44+
> **Note**: If a motion is playing that *also* controls this parameter, the motion might overwrite your manual value in the next `update()` call. To fix this, set the parameter *after* calling `model.update()`.

wiki_docs/Lifecycle-Management.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Lifecycle Management
2+
3+
Because this library relies on native C++ code, managing the lifecycle of the memory and the framework is crucial. If you don't do this correctly, your app might crash or leak memory.
4+
5+
## 1. Global Initialization
6+
7+
Before you do *anything* else (even before creating a model), you must initialize the Cubism Framework. This sets up the internal memory allocators and logging systems.
8+
9+
```java
10+
import dev.eatgrapes.live2d.CubismFramework;
11+
12+
// Call this ONCE at the start of your application
13+
CubismFramework.startUp();
14+
CubismFramework.initialize();
15+
```
16+
17+
> **Note**: This automatically extracts and loads the native `.dll`, `.so`, or `.dylib` from the jar file. You don't need to manually configure `java.library.path`.
18+
19+
## 2. Global Disposal
20+
21+
When your application is closing (e.g., in your window's close callback), you must tear down the framework to free native resources.
22+
23+
```java
24+
// Call this ONCE when your app is exiting
25+
CubismFramework.dispose();
26+
```
27+
28+
## 3. Model Lifecycle
29+
30+
Individual models (`CubismUserModel`) also have native resources. Always close them when you are done with a specific character, even if the app is still running.
31+
32+
```java
33+
CubismUserModel model = new CubismUserModel();
34+
35+
// ... use the model ...
36+
37+
// When switching characters or closing the level:
38+
model.close(); // IMPORTANT! Frees the C++ model instance
39+
```
40+
41+
**Pro Tip**: `CubismUserModel` implements `AutoCloseable`, so you can use it in try-with-resources blocks for short-lived tests, though usually, you'll keep it alive as a field in your renderer class.

wiki_docs/Loading-Assets.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Loading Assets
2+
3+
Live2D models are composed of several files. You need to load them in a specific order. The API expects `byte[]` arrays, so you can load these files from the disk, a JAR resource, or a network stream.
4+
5+
## 1. The Core Model (.moc3)
6+
7+
This is the geometry and structure of the character. It is **mandatory**.
8+
9+
```java
10+
byte[] mocBytes = Files.readAllBytes(Path.of("Hiyori.moc3"));
11+
CubismUserModel model = new CubismUserModel();
12+
model.loadModel(mocBytes);
13+
```
14+
15+
## 2. Poses (.pose3.json)
16+
17+
Poses handle "Part Sorting" and visibility. For example, hiding the arms when they go behind the back. It is **highly recommended**.
18+
19+
```java
20+
byte[] poseBytes = Files.readAllBytes(Path.of("Hiyori.pose3.json"));
21+
model.loadPose(poseBytes);
22+
```
23+
24+
## 3. Physics (.physics3.json)
25+
26+
This file controls the automatic movement of hair, clothes, and accessories based on the model's movement. Without this, the model will look very stiff.
27+
28+
```java
29+
byte[] physicsBytes = Files.readAllBytes(Path.of("Hiyori.physics3.json"));
30+
model.loadPhysics(physicsBytes);
31+
```
32+
33+
## 4. Textures
34+
35+
Textures are not loaded directly by the Live2D engine. Instead, **you** must load the image into OpenGL (using `STBImage` or similar) and give the Texture ID to the model.
36+
37+
```java
38+
// 1. Load image to OpenGL and get an ID (e.g., using LWJGL)
39+
int glTextureId = loadTexture("texture_00.png");
40+
41+
// 2. Register it with the model.
42+
// The index corresponds to the texture order in the .model3.json file.
43+
model.registerTexture(0, glTextureId);
44+
```
45+
46+
## 5. Renderer Creation
47+
48+
Once the model is loaded, you must initialize its internal renderer. This requires an active OpenGL context.
49+
50+
```java
51+
// Must be called on the render thread!
52+
model.createRenderer();
53+
```
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Motion & Expressions
2+
3+
Static models are boring! Here is how to make them move.
4+
5+
## Playing Motions
6+
7+
Motions are `.motion3.json` files. You load them as byte arrays and play them.
8+
9+
```java
10+
byte[] motionBytes = loadResource("tap_body.motion3.json");
11+
12+
// Priority:
13+
// 1 = Idle (can be interrupted)
14+
// 2 = Normal
15+
// 3 = Force (interrupts everything)
16+
int priority = 3;
17+
18+
// Loop: true/false
19+
boolean loop = false;
20+
21+
model.startMotion(motionBytes, priority, loop, name -> {
22+
System.out.println("Motion " + name + " finished!");
23+
});
24+
```
25+
26+
The model automatically fades between the current motion and the new one. You don't need to manage blending manually.
27+
28+
## Setting Expressions
29+
30+
Expressions are `.exp3.json` files that override specific parameters (like setting eyes to "happy").
31+
32+
1. **Load the Expression**:
33+
```java
34+
byte[] exprBytes = loadResource("f01.exp3.json");
35+
model.loadExpression(exprBytes, "Happy"); // Give it a unique name
36+
```
37+
38+
2. **Activate it**:
39+
```java
40+
model.setExpression("Happy");
41+
```
42+
43+
Expressions layer on top of motions. So if a motion blinks the eyes, but the expression forces them shut, they will stay shut.

wiki_docs/Rendering-Loop.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Rendering Loop
2+
3+
To verify the model is working, you need to update its state and draw it every frame. This typically happens inside your main game loop (e.g., GLFW loop).
4+
5+
## The Update Step
6+
7+
The `update` method advances the physics, fades motions, and calculates the new positions of all vertices.
8+
9+
```java
10+
// deltaTime: Time in seconds since the last frame (e.g., 0.016 for 60fps)
11+
model.update(deltaTime);
12+
```
13+
14+
> **Warning**: Do not pass `0` as delta time, as physics calculations may behave unpredictably.
15+
16+
## The Draw Step
17+
18+
The `draw` method issues the OpenGL commands to render the mesh. It requires a Model-View-Projection (MVP) matrix to position the model on your screen.
19+
20+
```java
21+
// A simple 4x4 Identity Matrix (Float array of size 16)
22+
float[] mvpMatrix = new float[] {
23+
1, 0, 0, 0,
24+
0, 1, 0, 0,
25+
0, 0, 1, 0,
26+
0, 0, 0, 1
27+
};
28+
29+
// Adjust for aspect ratio so the model doesn't look stretched
30+
float aspect = (float) windowWidth / windowHeight;
31+
mvpMatrix[0] = 1.0f / aspect; // Scale X by 1/aspect
32+
33+
model.draw(mvpMatrix);
34+
```
35+
36+
## Context Awareness
37+
38+
`model.draw()` calls OpenGL functions (`glDrawElements`, `glBindTexture`, etc.). Therefore, **it must be called from the thread that holds the OpenGL context**.

0 commit comments

Comments
 (0)