Skip to content

Commit 1a572a5

Browse files
committed
fix: improve hit detection precision and add drawable ID debugging
1 parent c520fe7 commit 1a572a5

3 files changed

Lines changed: 53 additions & 16 deletions

File tree

binding/src/main/java/dev/eatgrapes/live2d/CubismUserModel.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ private void onMotionFinished(String name) {
6363
public float getCanvasHeight() { return getCanvasHeightNative(_ptr); }
6464
private static native float getCanvasHeightNative(long ptr);
6565

66+
public String[] getDrawableIds() { return getDrawableIdsNative(_ptr); }
67+
private static native String[] getDrawableIdsNative(long ptr);
68+
6669
public void draw(float[] mvpMatrix) { drawNative(_ptr, mvpMatrix); }
6770
private static native void drawNative(long ptr, float[] mvpMatrix);
6871

example/src/main/java/dev/eatgrapes/live2d/example/Main.java

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,32 @@ private void init() {
4444
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
4545

4646
glfwSetCursorPosCallback(window, (win, x, y) -> {
47-
float nx = (float) (x / 400.0 - 1.0);
48-
float ny = (float) (1.0 - y / 400.0);
49-
if (model != null) model.setDragging(nx, ny);
47+
try (MemoryStack stack = MemoryStack.stackPush()) {
48+
IntBuffer wb = stack.mallocInt(1), hb = stack.mallocInt(1);
49+
glfwGetWindowSize(window, wb, hb);
50+
float nx = (float) (x / (wb.get(0) / 2.0) - 1.0);
51+
float ny = (float) (1.0 - y / (hb.get(0) / 2.0));
52+
if (model != null) model.setDragging(nx, ny);
53+
}
5054
});
5155

5256
glfwSetMouseButtonCallback(window, (win, button, action, mods) -> {
5357
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
5458
try (MemoryStack stack = MemoryStack.stackPush()) {
55-
DoubleBuffer x = stack.mallocDouble(1), y = stack.mallocDouble(1);
56-
glfwGetCursorPos(window, x, y);
57-
float nx = (float) (x.get(0) / 400.0 - 1.0);
58-
float ny = (float) (1.0 - y.get(0) / 400.0);
59+
DoubleBuffer xb = stack.mallocDouble(1), yb = stack.mallocDouble(1);
60+
IntBuffer wb = stack.mallocInt(1), hb = stack.mallocInt(1);
61+
glfwGetCursorPos(window, xb, yb);
62+
glfwGetWindowSize(window, wb, hb);
5963

60-
if (model.isHit("Head", nx, ny)) {
61-
System.out.println("Hit Head!");
62-
model.startMotion(load("/model/Hiyori/motions/Hiyori_m01.motion3.json"), 2, null);
63-
} else if (model.isHit("Body", nx, ny)) {
64+
float nx = (float) (xb.get(0) / (wb.get(0) / 2.0) - 1.0);
65+
float ny = (float) (1.0 - yb.get(0) / (hb.get(0) / 2.0));
66+
67+
if (model.isHit("HitArea", nx, ny)) {
6468
System.out.println("Hit Body!");
65-
model.startMotion(load("/model/Hiyori/motions/Hiyori_m02.motion3.json"), 2, null);
69+
model.startMotion(load("/model/Hiyori/motions/Hiyori_m04.motion3.json"), 2, null);
70+
} else if (model.isHit("ArtMesh12", nx, ny) || model.isHit("ArtMesh01", nx, ny)) {
71+
System.out.println("Hit Head/Face!");
72+
model.startMotion(load("/model/Hiyori/motions/Hiyori_m01.motion3.json"), 2, null);
6673
}
6774
} catch (Exception e) { e.printStackTrace(); }
6875
}
@@ -79,13 +86,25 @@ private void setup() throws Exception {
7986
model.loadPhysics(load("/model/Hiyori/Hiyori.physics3.json"));
8087
model.createRenderer();
8188

89+
System.out.println("Drawable IDs:");
90+
for (String id : model.getDrawableIds()) {
91+
System.out.println(" " + id);
92+
}
93+
8294
model.registerTexture(0, loadTex("/model/Hiyori/Hiyori.2048/texture_00.png"));
8395
model.registerTexture(1, loadTex("/model/Hiyori/Hiyori.2048/texture_01.png"));
8496
}
8597

8698
private void loop() {
8799
while (!glfwWindowShouldClose(window)) {
88100
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
101+
102+
try (MemoryStack stack = MemoryStack.stackPush()) {
103+
IntBuffer w = stack.mallocInt(1), h = stack.mallocInt(1);
104+
glfwGetWindowSize(window, w, h);
105+
glViewport(0, 0, w.get(0), h.get(0));
106+
}
107+
89108
model.update(0.016f);
90109
model.draw(mvp);
91110
glfwSwapBuffers(window);

native/src/CubismUserModel_JNI.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <Motion/CubismMotion.hpp>
66
#include <vector>
77
#include <string>
8-
#include <map>
8+
#include <iostream>
99

1010
using namespace Live2D::Cubism::Framework;
1111
using namespace Live2D::Cubism::Framework::Rendering;
@@ -34,7 +34,7 @@ class JniUserModel : public CubismUserModel {
3434

3535
void loadPoseCopy(const csmByte* buffer, csmSizeInt size) {
3636
_poseData.assign(buffer, buffer + size);
37-
LoadPose(_poseData.data(), (csmSizeInt)_poseData.size());
37+
LoadPose(_poseData.data(), (csmSizeInt)_physicsData.size());
3838
}
3939

4040
void startMotion(const csmByte* buffer, csmSizeInt size, int priority) {
@@ -62,10 +62,15 @@ class JniUserModel : public CubismUserModel {
6262

6363
void update(float dt) {
6464
if (!_model) return;
65+
6566
_model->LoadParameters();
66-
if (!_motionManager->IsFinished()) _motionManager->UpdateMotion(_model, dt);
67+
if (!_motionManager->IsFinished()) {
68+
_motionManager->UpdateMotion(_model, dt);
69+
}
6770
_model->SaveParameters();
6871

72+
if (_pose) _pose->UpdateParameters(_model, dt);
73+
6974
if (_dragManager) {
7075
_dragManager->Update(dt);
7176
auto* idm = CubismFramework::GetIdManager();
@@ -76,7 +81,6 @@ class JniUserModel : public CubismUserModel {
7681
_model->AddParameterValue(idm->GetId("ParamEyeBallY"), _dragManager->GetY());
7782
}
7883

79-
if (_pose) _pose->UpdateParameters(_model, dt);
8084
if (_physics) _physics->Evaluate(_model, dt);
8185
_model->Update();
8286
}
@@ -182,6 +186,17 @@ JNIEXPORT jfloat JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_getCanvasHeig
182186
return ((JniUserModel*)ptr)->GetModel()->GetCanvasHeight();
183187
}
184188

189+
JNIEXPORT jobjectArray JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_getDrawableIdsNative(JNIEnv* env, jclass, jlong ptr) {
190+
auto* model = ((JniUserModel*)ptr)->GetModel();
191+
int count = model->GetDrawableCount();
192+
jclass strCls = env->FindClass("java/lang/String");
193+
jobjectArray res = env->NewObjectArray(count, strCls, nullptr);
194+
for (int i = 0; i < count; i++) {
195+
env->SetObjectArrayElement(res, i, env->NewStringUTF(model->GetDrawableId(i)->GetString().GetRawString()));
196+
}
197+
return res;
198+
}
199+
185200
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_drawNative(JNIEnv* env, jclass, jlong ptr, jfloatArray matrix) {
186201
jfloat* m_ptr = env->GetFloatArrayElements(matrix, nullptr);
187202
CubismMatrix44 m;

0 commit comments

Comments
 (0)