Skip to content

Commit 0ac3860

Browse files
committed
fix: address memory leaks and implement hit-area specific motion mapping
1 parent c6d798a commit 0ac3860

2 files changed

Lines changed: 30 additions & 18 deletions

File tree

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ private void init() {
5757
float nx = (float) (x.get(0) / 400.0 - 1.0);
5858
float ny = (float) (1.0 - y.get(0) / 400.0);
5959

60-
if (model.isHit("HitArea", nx, ny)) {
61-
System.out.println("Hit!");
62-
byte[] motion = load("/model/Hiyori/motions/Hiyori_m01.motion3.json");
63-
model.startMotion(motion, 2, name -> System.out.println("Motion finished: " + name));
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+
System.out.println("Hit Body!");
65+
model.startMotion(load("/model/Hiyori/motions/Hiyori_m02.motion3.json"), 2, null);
6466
}
6567
} catch (Exception e) { e.printStackTrace(); }
6668
}

native/src/CubismUserModel_JNI.cpp

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

910
using namespace Live2D::Cubism::Framework;
1011
using namespace Live2D::Cubism::Framework::Rendering;
@@ -19,13 +20,24 @@ class JniUserModel : public CubismUserModel {
1920
~JniUserModel() {
2021
JNIEnv* env = getEnv();
2122
if (env) env->DeleteGlobalRef(_javaObj);
23+
// SDK's destructor handles _model, _renderer etc.
2224
}
2325

2426
void loadModelCopy(const csmByte* buffer, csmSizeInt size) {
2527
_mocData.assign(buffer, buffer + size);
2628
LoadModel(_mocData.data(), (csmSizeInt)_mocData.size());
2729
}
2830

31+
void loadPhysicsCopy(const csmByte* buffer, csmSizeInt size) {
32+
_physicsData.assign(buffer, buffer + size);
33+
LoadPhysics(_physicsData.data(), (csmSizeInt)_physicsData.size());
34+
}
35+
36+
void loadPoseCopy(const csmByte* buffer, csmSizeInt size) {
37+
_poseData.assign(buffer, buffer + size);
38+
LoadPose(_poseData.data(), (csmSizeInt)_poseData.size());
39+
}
40+
2941
void startMotion(const csmByte* buffer, csmSizeInt size, int priority) {
3042
auto* motion = CubismMotion::Create(buffer, size);
3143
if (!motion) return;
@@ -51,11 +63,8 @@ class JniUserModel : public CubismUserModel {
5163

5264
void update(float dt) {
5365
if (!_model) return;
54-
5566
_model->LoadParameters();
56-
if (!_motionManager->IsFinished()) {
57-
_motionManager->UpdateMotion(_model, dt);
58-
}
67+
if (!_motionManager->IsFinished()) _motionManager->UpdateMotion(_model, dt);
5968
_model->SaveParameters();
6069

6170
if (_dragManager) {
@@ -85,6 +94,8 @@ class JniUserModel : public CubismUserModel {
8594
JavaVM* _jvm;
8695
jobject _javaObj;
8796
std::vector<csmByte> _mocData;
97+
std::vector<csmByte> _physicsData;
98+
std::vector<csmByte> _poseData;
8899
};
89100

90101
extern "C" {
@@ -93,7 +104,7 @@ JNIEXPORT jlong JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_createNative(J
93104
return (jlong) new JniUserModel(env, thiz);
94105
}
95106

96-
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_deleteNative(JNIEnv* env, jclass, jlong ptr) {
107+
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_deleteNative(JNIEnv*, jclass, jlong ptr) {
97108
delete (JniUserModel*)ptr;
98109
}
99110

@@ -107,14 +118,14 @@ JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_loadModelNative
107118
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_loadPhysicsNative(JNIEnv* env, jclass, jlong ptr, jbyteArray buffer) {
108119
jsize len = env->GetArrayLength(buffer);
109120
jbyte* data = env->GetByteArrayElements(buffer, nullptr);
110-
((JniUserModel*)ptr)->LoadPhysics((const csmByte*)data, len);
121+
((JniUserModel*)ptr)->loadPhysicsCopy((const csmByte*)data, len);
111122
env->ReleaseByteArrayElements(buffer, data, JNI_ABORT);
112123
}
113124

114125
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_loadPoseNative(JNIEnv* env, jclass, jlong ptr, jbyteArray buffer) {
115126
jsize len = env->GetArrayLength(buffer);
116127
jbyte* data = env->GetByteArrayElements(buffer, nullptr);
117-
((JniUserModel*)ptr)->LoadPose((const csmByte*)data, len);
128+
((JniUserModel*)ptr)->loadPoseCopy((const csmByte*)data, len);
118129
env->ReleaseByteArrayElements(buffer, data, JNI_ABORT);
119130
}
120131

@@ -173,16 +184,15 @@ JNIEXPORT jfloat JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_getCanvasHeig
173184
}
174185

175186
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_drawNative(JNIEnv* env, jclass, jlong ptr, jfloatArray matrix) {
176-
auto* model = (JniUserModel*)ptr;
177-
auto* renderer = model->GetRenderer<CubismRenderer_OpenGLES2>();
187+
jfloat* m_ptr = env->GetFloatArrayElements(matrix, nullptr);
188+
CubismMatrix44 m;
189+
m.SetMatrix(m_ptr);
190+
auto* renderer = ((JniUserModel*)ptr)->GetRenderer<CubismRenderer_OpenGLES2>();
178191
if (renderer) {
179-
jfloat* m_ptr = env->GetFloatArrayElements(matrix, nullptr);
180-
CubismMatrix44 m;
181-
m.SetMatrix(m_ptr);
182192
renderer->SetMvpMatrix(&m);
183193
renderer->DrawModel();
184-
env->ReleaseFloatArrayElements(matrix, m_ptr, JNI_ABORT);
185194
}
195+
env->ReleaseFloatArrayElements(matrix, m_ptr, JNI_ABORT);
186196
}
187197

188-
}
198+
}

0 commit comments

Comments
 (0)