Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [5-r.1-beta.3] - 2024-01-18

### Added

* Add exception catching and error logging handling when an exception is thrown while loading a JSON file.

### Changed

* Change the compile and target SDK version of Android OS to 14.0 (API 34).
* Upgrade the version of Android Gradle Plugin from 8.0.2 to 8.1.1.
* Upgrade the version of Gradle from 8.1.1 to 8.2.
* Change the minimum version of Android Studio to Hedgehog(2023.1.1).
* Change the visibility of the `CubismPhysicsInternal` and `CubismPhysicsJson` classes to `public`.

### Fixed

* Fix an issue where models with a specific number of masks could not be drawn correctly.
* Replace deprecated notation in `build.gradle`.


## [5-r.1-beta.2] - 2023-09-28

### Added
Expand Down Expand Up @@ -134,6 +154,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

* New released!

[5-r.1-beta.3]: https://github.com/Live2D/CubismJavaFramework/compare/5-r.1-beta.2...5-r.1-beta.3
[5-r.1-beta.2]: https://github.com/Live2D/CubismJavaFramework/compare/5-r.1-beta.1...5-r.1-beta.2
[5-r.1-beta.1]: https://github.com/Live2D/CubismJavaFramework/compare/4-r.1...5-r.1-beta.1
[4-r.1]: https://github.com/Live2D/CubismJavaFramework/compare/4-r.1-beta.4...4-r.1
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.0.2'
classpath 'com.android.tools.build:gradle:8.1.1'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
2 changes: 1 addition & 1 deletion framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {

android {
namespace = "com.live2d.sdk.cubism.framework"
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
compileSdk PROP_COMPILE_SDK_VERSION.toInteger()

defaultConfig {
minSdkVersion PROP_MIN_SDK_VERSION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,12 @@ protected CubismMotion loadMotion(
byte[] buffer,
IFinishedMotionCallback onFinishedMotionHandler
) {
return CubismMotion.create(buffer, onFinishedMotionHandler);
try {
return CubismMotion.create(buffer, onFinishedMotionHandler);
} catch (Exception e) {
cubismLogError("Failed to loadMotion(). %s", e.getMessage());
return null;
}
}

/**
Expand All @@ -337,7 +342,7 @@ protected CubismMotion loadMotion(
* @return motion class
*/
protected CubismMotion loadMotion(byte[] buffer) {
return CubismMotion.create(buffer, null);
return loadMotion(buffer, null);
}

/**
Expand All @@ -347,7 +352,12 @@ protected CubismMotion loadMotion(byte[] buffer) {
* @return motion class
*/
protected CubismExpressionMotion loadExpression(final byte[] buffer) {
return CubismExpressionMotion.create(buffer);
try {
return CubismExpressionMotion.create(buffer);
} catch (Exception e) {
cubismLogError("Failed to loadExpressionMotion(). %s", e.getMessage());
return null;
}
}

/**
Expand All @@ -356,7 +366,11 @@ protected CubismExpressionMotion loadExpression(final byte[] buffer) {
* @param buffer a buffer where pose3.json is loaded.
*/
protected void loadPose(final byte[] buffer) {
pose = CubismPose.create(buffer);
try {
pose = CubismPose.create(buffer);
} catch (Exception e) {
cubismLogError("Failed to loadPose(). %s", e.getMessage());
}
}

/**
Expand All @@ -365,7 +379,11 @@ protected void loadPose(final byte[] buffer) {
* @param buffer a buffer where physics3.json is loaded.
*/
protected void loadPhysics(final byte[] buffer) {
physics = CubismPhysics.create(buffer);
try {
physics = CubismPhysics.create(buffer);
} catch (Exception e) {
cubismLogError("Failed to loadPhysics(). %s", e.getMessage());
}
}

/**
Expand All @@ -374,7 +392,11 @@ protected void loadPhysics(final byte[] buffer) {
* @param buffer a buffer where userdata3.json is loaded.
*/
protected void loadUserData(final byte[] buffer) {
modelUserData = CubismModelUserData.create(buffer);
try {
modelUserData = CubismModelUserData.create(buffer);
} catch (Exception e) {
cubismLogError("Failed to loadUserData(). %s", e.getMessage());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* Internal data of CubismPhysics.
*/
class CubismPhysicsInternal {
public class CubismPhysicsInternal {
/**
* Types of physics operations to be applied.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
/**
* A manager of physics3.json.
*/
class CubismPhysicsJson {
public class CubismPhysicsJson {
/**
* Constructor
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void addClippedDrawable(int drawableIndex) {
/**
* RGBAのいずれのチャンネルにこのクリップを配置するか(0:R, 1:G, 2:B, 3:A)
*/
public int layoutChannelNo;
public int layoutChannelIndex;

/**
* マスク用チャンネルのどの領域にマスクを入れるか(View座標-1..1, UVは0..1に直す)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public void setupLayoutBounds(int usingClipCount) {
for (int index = 0; index < clippingContextListForMask.size(); index++) {
T_ClippingContext cc = clippingContextListForMask.get(index);

cc.layoutChannelNo = 0; // どうせ毎回消すので固定で良い
cc.layoutChannelIndex = 0; // どうせ毎回消すので固定で良い
cc.layoutBounds.setX(0.0f);
cc.layoutBounds.setY(0.0f);
cc.layoutBounds.setWidth(1.0f);
Expand All @@ -272,25 +272,31 @@ public void setupLayoutBounds(int usingClipCount) {

// ひとつのRenderTextureを極力いっぱいに使ってマスクをレイアウトする。
// マスクグループの数が4以下ならRGBA各チャンネルに1つずつマスクを配置し、5以上6以下ならRGBAを2,2,1,1と配置する。
int countPerSheetDiv = usingClipCount / renderTextureCount; // レンダーテクスチャ1枚あたり何枚割り当てるか
int countPerSheetMod = usingClipCount % renderTextureCount; // この番号のレンダーテクスチャまでに1つずつ配分する。
// NOTE: 1枚に割り当てるマスクの分割数を取りたいため、小数点は切り上げる。
final int countPerSheetDiv = (usingClipCount + renderTextureCount - 1) / renderTextureCount; // レンダーテクスチャ1枚あたり何枚割り当てるか
final int reduceLayoutTextureCount = usingClipCount % renderTextureCount; // レイアウトの数を1枚減らすレンダーテクスチャの数(この数だけのレンダーテクスチャが対象)。

// RGBAを順番に使っていく。
final int div = countPerSheetDiv / COLOR_CHANNEL_COUNT; // 1チャンネルに配置する基本のマスク個数
final int mod = countPerSheetDiv % COLOR_CHANNEL_COUNT; // 余り、この番号のチャンネルまでに1つずつ配分する
final int divCount = countPerSheetDiv / COLOR_CHANNEL_COUNT; // 1チャンネルに配置する基本のマスク個数
final int modCount = countPerSheetDiv % COLOR_CHANNEL_COUNT; // 余り、この番号のチャンネルまでに1つずつ配分する(インデックスではない)

// RGBAそれぞれのチャンネルを用意していく(0:R , 1:G , 2:B, 3:A, )
int curClipIndex = 0; // 順番に設定していく

for (int renderTextureNo = 0; renderTextureNo < renderTextureCount; renderTextureNo++) {
for (int channelNo = 0; channelNo < COLOR_CHANNEL_COUNT; channelNo++) {
for (int renderTextureIndex = 0; renderTextureIndex < renderTextureCount; renderTextureIndex++) {
for (int channelIndex = 0; channelIndex < COLOR_CHANNEL_COUNT; channelIndex++) {
// このチャンネルにレイアウトする数
int layoutCount = div + (channelNo < mod ? 1 : 0);
// NOTE: レイアウト数 = 1チャンネルに配置する基本のマスク + 余りのマスクを置くチャンネルなら1つ追加
int layoutCount = divCount + (channelIndex < modCount ? 1 : 0);

// このレンダーテクスチャにまだ割り当てられていなければ追加する
final int checkChannelNo = mod + 1 >= COLOR_CHANNEL_COUNT ? 0 : mod + 1;
if (layoutCount < layoutCountMaxValue && channelNo == checkChannelNo) {
layoutCount += renderTextureNo < countPerSheetMod ? 1 : 0;
// レイアウトの数を1枚減らす場合にそれを行うチャンネルを決定
// divが0の時は正常なインデックスの範囲になるように調整
final int checkChannelIndex = modCount + (divCount < 1 ? -1 : 0);

// 今回が対象のチャンネルかつ、レイアウトの数を1枚減らすレンダーテクスチャが存在する場合
if (channelIndex == checkChannelIndex && reduceLayoutTextureCount > 0) {
// 現在のレンダーテクスチャが、対象のレンダーテクスチャであればレイアウトの数を1枚減らす。
layoutCount -= !(renderTextureIndex < reduceLayoutTextureCount) ? 1 : 0;
}

// 分割方法を決定する。
Expand All @@ -299,21 +305,21 @@ public void setupLayoutBounds(int usingClipCount) {
} else if (layoutCount == 1) {
// 全てをそのまま使う。
T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++);
cc.layoutChannelNo = channelNo;
cc.layoutChannelIndex = channelIndex;
csmRectF bounds = cc.layoutBounds;

bounds.setX(0.0f);
bounds.setY(0.0f);
bounds.setWidth(1.0f);
bounds.setHeight(1.0f);

cc.bufferIndex = renderTextureNo;
cc.bufferIndex = renderTextureIndex;
} else if (layoutCount == 2) {
for (int i = 0; i < layoutCount; i++) {
final int xpos = i % 2;

T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++);
cc.layoutChannelNo = channelNo;
cc.layoutChannelIndex = channelIndex;
csmRectF bounds = cc.layoutBounds;

// UVを2つに分解して使う
Expand All @@ -322,7 +328,7 @@ public void setupLayoutBounds(int usingClipCount) {
bounds.setWidth(0.5f);
bounds.setHeight(1.0f);

cc.bufferIndex = renderTextureNo;
cc.bufferIndex = renderTextureIndex;
}
} else if (layoutCount <= 4) {
// 4分割して使う
Expand All @@ -331,15 +337,15 @@ public void setupLayoutBounds(int usingClipCount) {
final int ypos = i / 2;

T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++);
cc.layoutChannelNo = channelNo;
cc.layoutChannelIndex = channelIndex;
csmRectF bounds = cc.layoutBounds;

bounds.setX(xpos * 0.5f);
bounds.setY(ypos * 0.5f);
bounds.setWidth(0.5f);
bounds.setHeight(0.5f);

cc.bufferIndex = renderTextureNo;
cc.bufferIndex = renderTextureIndex;
}
} else if (layoutCount <= layoutCountMaxValue) {
// 9分割して使う
Expand All @@ -348,15 +354,15 @@ public void setupLayoutBounds(int usingClipCount) {
final int ypos = i / 3;

T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++);
cc.layoutChannelNo = channelNo;
cc.layoutChannelIndex = channelIndex;
csmRectF bounds = cc.layoutBounds;

bounds.setX(xpos / 3.0f);
bounds.setY(ypos / 3.0f);
bounds.setWidth(1.0f / 3.0f);
bounds.setHeight(1.0f / 3.0f);

cc.bufferIndex = renderTextureNo;
cc.bufferIndex = renderTextureIndex;
}
}
// マスクの制限枚数を超えた場合の処理
Expand All @@ -376,7 +382,7 @@ public void setupLayoutBounds(int usingClipCount) {
// もちろん描画結果はろくなことにならない。
for (int i = 0; i < layoutCount; i++) {
T_ClippingContext cc = clippingContextListForMask.get(curClipIndex++);
cc.layoutChannelNo = 0;
cc.layoutChannelIndex = 0;

csmRectF bounds = cc.layoutBounds;
bounds.setX(0.0f);
Expand Down Expand Up @@ -407,8 +413,8 @@ public int getRenderTextureCount() {
}

@Override
public CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelNo) {
return channelColors.get(channelNo);
public CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelIndex) {
return channelColors.get(channelIndex);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ void createMatrixForMask(
/**
* カラーチャンネル(RGBA)のフラグを取得する。
*
* @param channelNo カラーチャンネル(RGBA)の番号(0:R, 1:G, 2:B, 3:A)
* @param channelIndex カラーチャンネル(RGBA)の番号(0:R, 1:G, 2:B, 3:A)
* @return カラーチャンネルのフラグ
*/
CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelNo);
CubismRenderer.CubismTextureColor getChannelFlagAsColor(int channelIndex);
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ public void close() {
/**
* Bind processing of OpenGL textures.
*
* @param modelTextureNo number of the model texture to set
* @param glTextureNo number of the OpenGL texture to bind
* @param modelTextureIndex number of the model texture to set
* @param glTextureIndex number of the OpenGL texture to bind
*/
public void bindTexture(int modelTextureNo, int glTextureNo) {
textures.put(modelTextureNo, glTextureNo);
public void bindTexture(int modelTextureIndex, int glTextureIndex) {
textures.put(modelTextureIndex, glTextureIndex);
areTexturesChanged = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ public void setupShaderProgramForDraw(
);

// Set used color channel.
final int channelNumber = renderer.getClippingContextBufferForDraw().layoutChannelNo;
final int channelIndex = renderer.getClippingContextBufferForDraw().layoutChannelIndex;
CubismRenderer.CubismTextureColor colorChannel = renderer
.getClippingContextBufferForDraw()
.getClippingManager()
.getChannelFlagAsColor(channelNumber);
.getChannelFlagAsColor(channelIndex);
glUniform4f(
shaderSet.uniformChannelFlagLocation,
colorChannel.r,
Expand Down Expand Up @@ -290,11 +290,11 @@ public void setupShaderProgramForMask(
);

// channels
final int channelNumber = renderer.getClippingContextBufferForMask().layoutChannelNo;
final int channelIndex = renderer.getClippingContextBufferForMask().layoutChannelIndex;
CubismRenderer.CubismTextureColor colorChannel = renderer
.getClippingContextBufferForMask()
.getClippingManager()
.getChannelFlagAsColor(channelNumber);
.getChannelFlagAsColor(channelIndex);

glUniform4f(
shaderSet.uniformChannelFlagLocation,
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Android SDK version that will be used as the compiled project
PROP_COMPILE_SDK_VERSION=33
PROP_COMPILE_SDK_VERSION=34
# Android SDK version that will be used as the earliest version of android this application can run on
PROP_MIN_SDK_VERSION=21
# Android SDK version that will be used as the latest version of android this application has been tested on
PROP_TARGET_SDK_VERSION=33
PROP_TARGET_SDK_VERSION=34
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Jul 11 18:25:17 JST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists